Last active
August 29, 2015 14:26
-
-
Save RossRogers/22cef9abc7346ecbfe33 to your computer and use it in GitHub Desktop.
This file contains 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
from django.core.management.base import BaseCommand, CommandError | |
from django.conf import settings | |
import rest_framework | |
from collections import namedtuple | |
import re,sys | |
INDENT = ' '*2 | |
# TODO(rrogers) 2015.06.01 - allow canonical, global nested-objects and | |
# automatically swap them in? | |
# | |
# If a model is marked as globally_canonical, then 1 and only 1 version of that | |
# model exists | |
# | |
# * post_restore on such an object should register its `url` globally and | |
# anyone wishing to get a reference should look in the hash | |
# | |
# * should updates from the server be golden? or should local state take | |
# precedence? | |
# | |
# * fields referencing canonical objects have a property in the place of | |
# reference url fields in order to spoof out and obviate the need for | |
# manual field obj/url alias sync'ing. | |
# | |
class Command(BaseCommand): | |
help = 'Generates a js interface from the Rest Framework serializers' | |
def add_arguments(self, parser): | |
parser.add_argument('output_path', nargs='+', type=str) | |
parser.add_argument('base_factory_name', nargs='+', type=str) | |
parser.add_argument('server_base_url', nargs='+', type=str) | |
def handle(self, *args, **options): | |
from django.core.urlresolvers import RegexURLPattern, RegexURLResolver | |
from django.utils.termcolors import colorize | |
import os, sys | |
(output_path,base_factory_name) = args[:2] | |
server_base_url = args[2] if len(args) > 2 else '/rest' | |
server_base_url = server_base_url.rstrip('/')+'/' | |
from qc_srvr.urls import urlpatterns | |
serializer_2_class = {} | |
ClassDefn = namedtuple('ClassDefn',('url_name','fields','meta')) | |
FieldDefn = namedtuple('FieldDefn',('field_name','type','meta','instance_class_name')) | |
def traverse(url_patterns, prefix=''): | |
for p in url_patterns: | |
if isinstance(p, RegexURLPattern): | |
composed = '%s%s' % (prefix, p.regex.pattern) | |
#print '\t%s' % (composed), '==> ' | |
#sys.stdout.write('%s.' % p.callback.__module__) | |
viewset = getattr(p.callback,'cls',None) | |
if not viewset: | |
continue | |
viewset = viewset() # create instance | |
if not isinstance(viewset,rest_framework.viewsets.ModelViewSet): | |
continue | |
serializer_class = getattr(viewset,'serializer_class',None) | |
if not serializer_class: | |
continue | |
serializer = serializer_class() | |
model = getattr(serializer.Meta,'model') | |
full_serializer_type = serializer.__module__+'.'+serializer.__class__.__name__ | |
url = re.compile(r'^\^*((?:\w+/?)+)').search(composed).group(1) | |
url_name = url.strip('/').split('/') | |
class_defn = ClassDefn(url_name,[],{}) | |
class_defn.meta['url'] = server_base_url + url | |
class_defn.meta['is_list_class'] = p.callback.suffix == 'List' | |
if class_defn.meta['is_list_class']: | |
class_defn.meta['instance_class_name'] = url_name[-1] | |
# class_defn.meta['instance_class_full_name'] = base_factory_name + '.' + '.'.join(url_name) | |
if p.callback.suffix == 'List': | |
url_name[-1] += p.callback.suffix | |
full_serializer_type += p.callback.suffix | |
if full_serializer_type in serializer_2_class: | |
pass | |
# if -1 != composed.find('PackingInstr/'): | |
# import rpdb2;rpdb2.start_embedded_debugger('foo') | |
# print 'WARNING: entry',full_serializer_type,'already exists in serializer_2_class. \n\told defn:',serializer_2_class[full_serializer_type],'\n\tnew defn:',class_defn | |
serializer_2_class[full_serializer_type] = class_defn | |
model_fields = {} | |
for field in sorted(model._meta.concrete_fields + model._meta.many_to_many + model._meta.virtual_fields): | |
model_fields[field.name] = field | |
if class_defn.meta['is_list_class']: | |
def a(f): | |
class_defn.fields.append(f) | |
#a(FieldDefn('count','number',{'is_integer':True},None)) | |
#a(FieldDefn('next','string',{},None)) | |
#a(FieldDefn('previous','string',{},None)) | |
f = FieldDefn('results','Array< '+class_defn.meta['instance_class_name'] + ' >',{},class_defn.meta['instance_class_name']) | |
class_defn.fields.append(f) | |
else : | |
#DRF3.+for f_name,f in serializer.fields.fields.iteritems(): | |
for f_name,f in serializer.fields.iteritems(): | |
t = None | |
field_meta = {} | |
# DRF3.+if isinstance(f,rest_framework.relations.ManyRelatedField): | |
if isinstance(f,rest_framework.relations.RelatedField): | |
#import rpdb2;rpdb2.start_embedded_debugger('foo') | |
f = getattr(serializer_class,f_name,f) | |
# DRF3.+ | |
# many = isinstance(f,rest_framework.serializers.ListSerializer) or isinstance(f,rest_framework.relations.ManyRelatedField) | |
# if isinstance(f,rest_framework.serializers.ListSerializer): | |
# f = getattr(f,'child',f) | |
# f.many = many | |
f.many = getattr(f,'many',False) | |
# if f_name == 'header_sample_requirements': | |
# import rpdb2;rpdb2.start_embedded_debugger('foo') | |
#print f_name | |
#if f_name.endswith('user_permissions'): | |
# import rpdb2;rpdb2.start_embedded_debugger('foo') | |
if isinstance(f,rest_framework.fields.BooleanField): t = 'boolean' | |
elif isinstance(f,rest_framework.fields.CharField): t = 'String' | |
elif isinstance(f,rest_framework.fields.URLField): t = 'String' | |
elif isinstance(f,rest_framework.fields.SlugField): t = 'String' | |
elif isinstance(f,rest_framework.fields.ChoiceField): t = 'String' | |
elif isinstance(f,rest_framework.fields.EmailField): t = 'String' | |
elif isinstance(f,rest_framework.fields.RegexField): t = 'String' | |
elif isinstance(f,rest_framework.fields.DateField): | |
t = 'Date' | |
field_meta['is_date_only_field'] = True | |
elif isinstance(f,rest_framework.fields.DateTimeField): t = 'Date' | |
elif isinstance(f,rest_framework.fields.TimeField): | |
t = 'Date' | |
field_meta.is_time_only_field | |
elif isinstance(f,rest_framework.fields.IntegerField): | |
t = 'number' | |
field_meta['is_integer'] = True | |
elif isinstance(f,rest_framework.fields.FloatField): t = 'number' | |
elif isinstance(f,rest_framework.fields.DecimalField): t = 'number' | |
elif isinstance(f,rest_framework.relations.HyperlinkedIdentityField): t = 'String' | |
elif isinstance(f,rest_framework.relations.HyperlinkedRelatedField): | |
t = 'String' | |
field_meta['is_url'] = True | |
elif isinstance(f,rest_framework.relations.PrimaryKeyRelatedField): | |
t = 'number' | |
field_meta['is_integer'] = True | |
elif isinstance(f,rest_framework.serializers.Serializer): | |
def getter(module_name,many): | |
def inner(): | |
return ('Array< ' if many else '')+\ | |
base_factory_name + '.' + \ | |
'.'.join(serializer_2_class[module_name].url_name) +\ | |
(' >' if many else '') | |
return inner | |
field_meta['field_is_delegate_serializer'] = True | |
if f.many: | |
field_meta['is_array'] = True | |
field_meta['inst_type'] = getter(f.__module__+'.'+f.__class__.__name__,False) | |
t = getter(f.__module__+'.'+f.__class__.__name__,f.many) | |
elif isinstance(f,rest_framework.serializers.Field): t = 'String' | |
else: | |
print >>sys.stderr, "ERROR: Couldn't figure out field",f_name,"for serializer",full_serializer_type | |
t = 'String' | |
if getattr(f,'many',False) and not isinstance(f,rest_framework.serializers.Serializer): | |
field_meta['is_array'] = True | |
field_meta['inst_type'] = t | |
t = 'Array< '+t +' >' | |
if not t: | |
import rpdb2;rpdb2.start_embedded_debugger('foo') | |
class_defn.fields.append(FieldDefn(f_name,t,field_meta,None)) | |
if isinstance(p, RegexURLResolver): | |
traverse(p.url_patterns, prefix=p.regex.pattern) | |
traverse(urlpatterns) | |
#import rpdb2;rpdb2.start_embedded_debugger('foo') | |
base_module = {} | |
print '' | |
for serializer_name,cls in serializer_2_class.iteritems(): | |
module = base_module | |
for u in cls.url_name[:-1]: | |
module = module.setdefault(u,{}) | |
module[cls.url_name[-1]] = cls | |
#print serializer_name, '.'.join(cls.url_name) | |
for f in cls.fields: | |
pass | |
#print ' ',f.field_name,':',(f.type() if callable(f.type) else f.type) | |
#print len(cls.fields) | |
out = open(output_path,'w') if len(args) > 0 else sys.stdout | |
def w(s): | |
out.write(s) | |
out.write('\n') | |
w("'use strict';") | |
w('function pad2(num) {') | |
w(INDENT + "return ('0'+num).slice(-2)") | |
w('}') | |
w('var TIMEZONE_OFFSET = new Date().getTimezoneOffset();') | |
w('var TIMEZONE_OFFSET_MS = TIMEZONE_OFFSET*60*1000;') | |
w('var TIMEZONE_OFFSET_MS_PADDED = (TIMEZONE_OFFSET+12*60)*60*1000;') | |
w("var TIMEZONE_ISO_TIME = 'T' + pad2(TIMEZONE_OFFSET/60 + 12) +") | |
w(INDENT + "':' + pad2(TIMEZONE_OFFSET%60) + ':00.000Z'") | |
w('') | |
w('var '+base_factory_name+' = {};') | |
w('(function ('+base_factory_name+') {') | |
def OutputClasses(module,module_names=[],indent=''): | |
def keep_list_close_to_inst_cmp(a,b): | |
a_stripped = a | |
a_is_list = a[-4:] == 'List' | |
if a_is_list: | |
a_stripped = a[:-4] | |
b_stripped = b | |
b_is_list = b[-4:] == 'List' | |
if b_is_list: | |
b_stripped = b[:-4] | |
if a_stripped == b_stripped: | |
return cmp(a,b) | |
return cmp(a_stripped,b_stripped) | |
keys = sorted(module.keys(),keep_list_close_to_inst_cmp) | |
factory_lines = [] | |
indent_child = indent + INDENT | |
for mod_class_name in keys: | |
mod_class = module[mod_class_name] | |
if isinstance(mod_class,ClassDefn): | |
cls = mod_class | |
cls_name = mod_class_name | |
indent_g_child = indent_child + INDENT | |
indent_gg_child = indent_child + 2 * INDENT | |
indent_ggg_child = indent_child + 3 * INDENT | |
indent_gggg_child = indent_child + 4 * INDENT | |
indent_ggggg_child = indent_child + 5 * INDENT | |
indent_gggggg_child = indent_child + 6 * INDENT | |
encapsulating_module = module_names[-1] | |
w(indent_child + encapsulating_module +'.' + cls_name + ' = (function() {') | |
w('') | |
len_longest_field_name = reduce(lambda accum,f: max(accum,len(f.field_name)),cls.fields,0) | |
field_name_formatter = '%%-%ds'%len_longest_field_name | |
if cls.meta['is_list_class']: | |
w(indent_g_child + 'function '+cls_name+'() {') | |
# w(indent_gg_child + 'this.count = null') | |
# w(indent_gg_child + 'this.next = null') | |
# w(indent_gg_child + 'this.previous = null') | |
w(indent_gg_child + 'this.results = []') | |
w(indent_g_child +'}') | |
w('') | |
w(indent_g_child + cls_name + '.get = function(parameters, config, destination) {') | |
w(indent_gg_child + "var url = '" + cls.meta['url'] + "'") | |
w(indent_gg_child + "if (parameters) { url += '?'+parameters }") | |
w(indent_gg_child + 'destination = destination || new '+cls_name+'()') | |
w(indent_gg_child + 'var post_restore_intercept = function(data) {') | |
w(indent_ggg_child + 'var d = data.data;') | |
w(indent_ggg_child + 'destination.count = parseInt(d.count)') | |
w(indent_ggg_child + 'destination.next = d.next') | |
w(indent_ggg_child + 'destination.previous = d.previous') | |
w(indent_ggg_child + 'destination.results = []') | |
w(indent_ggg_child + 'var list_element_promises = [];') | |
w(indent_ggg_child + 'd.results.forEach(function(_,i) {') | |
w(indent_gggg_child + 'var element_promise = ' + encapsulating_module+'.'+cls.meta['instance_class_name'] + '.post_restore(d.results[i])') | |
w(indent_gggg_child + 'list_element_promises.push(element_promise);') | |
w(indent_gggg_child + 'destination.results.push(element_promise);') | |
w(indent_gggg_child + 'element_promise.then(function(el) { destination.results[i] = el; });') | |
w(indent_ggg_child + '})') | |
w(indent_ggg_child + 'if (list_element_promises.length) {') | |
w(indent_gggg_child + 'return ' + base_factory_name + '.$q.all(list_element_promises).then(function(){ return destination });') | |
w(indent_ggg_child + '} else {') | |
w(indent_gggg_child + 'return destination') | |
w(indent_ggg_child + '}') | |
w(indent_gg_child + '}') | |
w(indent_gg_child + "config = config || {}") | |
w(indent_gg_child + 'return ' + base_factory_name + '.$http.get(url,config).then(post_restore_intercept);') | |
w(indent_g_child + '}') | |
w(indent_g_child + cls_name + '.prototype.get = function(parameters, config) {') | |
w(indent_gg_child + 'return '+ cls_name + '.get(parameters, config, this)') | |
w(indent_g_child + '}') | |
else: | |
w(indent_g_child + 'function '+cls_name+'() {') | |
for f in cls.fields: | |
if 'is_array' in f.meta: | |
w(indent_gg_child + 'this.' + f.field_name + ' = []') | |
else: | |
pass | |
# w(indent_gg_child + 'this.' + f.field_name + ' = null') | |
w(indent_g_child +'}') | |
w('') | |
w(indent_g_child + cls_name + ".prototype.base_url = '" + cls.meta['url'] + "'") | |
w('') | |
w(indent_g_child + cls_name+'.prototype.pre_save = function() {') | |
w(indent_gg_child + 'var self = this;') | |
w(indent_gg_child + 'return ' + base_factory_name + '.$q(function(resolve,reject) {') | |
w(indent_ggg_child + 'var result = self;') | |
w(indent_ggg_child + 'var child_pre_save_promises = [];') | |
saving_a_clone = {'yup':False} | |
def ensure_cloned_result(indent=0): | |
if not saving_a_clone['yup']: | |
saving_a_clone['yup'] = True | |
w(indent_ggg_child + indent*INDENT + 'result = $.extend({},result)') | |
for f in cls.fields: | |
data_manipulation_func = None | |
if 'is_date_only_field' in f.meta: | |
ensure_cloned_result() | |
data_manipulation_func = lambda src, dest: 'if ('+src+' && '+src+'.toISOString) { ' + dest +' = '+ src + '.toISOString().slice(0,10)}' | |
elif 'field_is_delegate_serializer' in f.meta: | |
ensure_cloned_result() | |
data_manipulation_func = lambda src,dest: ( | |
'if ('+src + ' && '+src+'.pre_save) {\n' + | |
indent_ggggg_child + 'var p = ' +dest + ' = ' + src + '.pre_save();\n' + | |
indent_ggggg_child + 'child_pre_save_promises.push(p);\n' + | |
indent_ggggg_child + 'p.then(function(promise_result){ ' + dest + '= promise_result; })\n' + | |
indent_gggg_child + '} else {\n' + | |
indent_ggggg_child + dest + ' = ' + src + '\n' + indent_gggg_child + '\n' + | |
indent_gggg_child + '}') | |
if data_manipulation_func: | |
if 'is_array' in f.meta: | |
w(indent_ggg_child + 'result.'+f.field_name+' = []') | |
w(indent_ggg_child + 'self.'+f.field_name + '.forEach( function(_,i) {') | |
w(indent_gggg_child + data_manipulation_func('self.'+f.field_name+'[i]','result.'+f.field_name+'[i]')) | |
w(indent_ggg_child + '})') | |
else: | |
w(indent_ggg_child + data_manipulation_func('result.'+f.field_name,'result.'+f.field_name)) | |
w(indent_ggg_child + 'if (child_pre_save_promises.length) {') | |
w(indent_gggg_child + 'resolve(' + base_factory_name + '.$q.all(child_pre_save_promises).then(function() { return result;}))') | |
w(indent_ggg_child + '} else {') | |
w(indent_gggg_child + 'resolve(result);') | |
w(indent_ggg_child + '}') | |
w(indent_g_child + '})}') | |
w('') | |
w(indent_g_child + cls_name+'.post_restore = function(json_obj, destination) {') | |
w(indent_gg_child + 'return ' + base_factory_name + '.$q( function(resolve, reject) {') | |
w(indent_ggg_child + 'var result = destination || new ' + cls_name + '()') | |
w(indent_ggg_child + 'if (json_obj === null) {') | |
w(indent_gggg_child + 'result = json_obj') | |
w(indent_gggg_child + 'resolve(result);') | |
w(indent_ggg_child + '}') | |
w(indent_ggg_child + "if (typeof(json_obj) === 'undefined') {") | |
w(indent_gggg_child + 'resolve(result)') | |
w(indent_ggg_child + '}') | |
w(indent_ggg_child + 'var child_post_resolve_promises = [];') | |
def next_inst_cnt(): | |
inst_cnt = 0 | |
for i in xrange(0,1000): | |
inst_cnt += 1 | |
yield inst_cnt | |
next_inst_cnt = next_inst_cnt() | |
for f in cls.fields: | |
t = f.type() if callable(f.type) else f.type | |
inst_type = t | |
if 'is_array' in f.meta: | |
inst_type = f.meta['inst_type'] | |
if callable(inst_type): | |
inst_type = inst_type() | |
data_manipulation_func = None | |
if 'is_date_only_field' in f.meta: | |
data_manipulation_func = lambda src,dest: 'if ('+src+" && (typeof("+dest+") === 'undefined' || "+dest+" === null)) "+ dest + ' = new Date('+src+'+TIMEZONE_ISO_TIME);' | |
elif 'is_integer' in f.meta: | |
data_manipulation_func = lambda src,dest: "if ("+src+" !== null && (typeof("+dest+") === 'undefined' || "+dest+" === null)) "+dest + " = parseInt(" + src + ");" | |
elif 'field_is_delegate_serializer' in f.meta: | |
data_manipulation_func = lambda src,dest: src + ' && child_post_resolve_promises.push('+ inst_type + '.post_restore(' + src + ', '+dest+').then(function(sub_result) { ' + dest + '= sub_result;}));' | |
elif t == 'Date': | |
data_manipulation_func = lambda src,dest: 'if ('+src+" && (typeof("+dest+") === 'undefined' || "+dest+" === null)) "+dest + ' = new Date('+src+');' | |
elif t == 'number': | |
data_manipulation_func = lambda src,dest: "if ("+src+" !== null && (typeof("+dest+") === 'undefined' || "+dest+" === null)) "+dest + ' = parseFloat('+src+');' | |
else: | |
#if 'is_url' in f.meta: | |
# def data_manipulation_func(src,dest,idx=None): | |
# dest_obj = dest +'__obj' | |
# result = [ | |
# 'if ('+src+" && (typeof("+dest+") === 'undefined' || "+dest+" === null)) {", | |
# INDENT + dest + ' = ' + src + ';', | |
# if idx is not None: | |
# result.append( INDENT*2 + dest_obj + ' = ' + dest_obj + ' || []') | |
# result.extend([ | |
# INDENT*2 + base_factory_name + ".$http.get('" + src +"')", | |
# INDENT*3 + ".success(function(data) {", | |
# INDENT*4 + dest + '__obj' + ('' if idx is None else '['+idx+']')+ ' = data', | |
# INDENT*3 + "})", | |
# INDENT + "}", | |
# '}' | |
# ]) | |
# return result | |
#else: | |
data_manipulation_func = lambda src,dest:\ | |
'if ('+src+" && (typeof("+dest+") === 'undefined' || "+dest+" === null)) " + dest + ' = ' + src + ';' | |
if data_manipulation_func: | |
if 'is_array' in f.meta: | |
w(indent_ggg_child + 'result.'+f.field_name + ' = ' + 'result.'+f.field_name + ' || []') | |
w(indent_ggg_child + 'json_obj.'+f.field_name+'.forEach(function(_,i) {') | |
inst_class = f.meta['inst_type'] | |
if callable(inst_class): | |
inst_class = inst_class() | |
inst_name = 'inst_' + str(next_inst_cnt.next()) | |
w(indent_gggg_child + 'if (i < result.'+f.field_name+'.length) {') | |
w(indent_ggggg_child + 'var ' + inst_name + ' = result.'+f.field_name+'[i]') | |
w(indent_gggg_child + '} else {') | |
if inst_class == 'String': | |
w(indent_ggggg_child + 'result.'+f.field_name+'.push(null)') | |
else: | |
w(indent_ggggg_child + 'var ' + inst_name + ' = new '+inst_class+'()') | |
w(indent_ggggg_child + 'result.'+f.field_name+'.push('+inst_name+')') | |
w(indent_gggg_child + '}') | |
#if 'is_url' in f.meta: | |
# w(indent_gggg_child + ('\n'+indent_gggg_child).join(data_manipulation_func('json_obj.'+f.field_name,inst_name,'i'))) | |
#else: | |
if 1: | |
w(indent_gggg_child + data_manipulation_func('json_obj.'+f.field_name+'[i]','result.'+f.field_name+'[i]')) | |
w(indent_ggg_child + '})') | |
else: | |
#if 'is_url' in f.meta: | |
# w(indent_ggg_child + ('\n'+indent_ggg_child).join(data_manipulation_func('json_obj.'+f.field_name,'result.'+f.field_name))) | |
#else: | |
w(indent_ggg_child + data_manipulation_func('json_obj.'+f.field_name,'result.'+f.field_name)) | |
w(indent_ggg_child + 'if (child_post_resolve_promises.length) {') | |
w(indent_gggg_child + 'resolve(' + base_factory_name + '.$q.all(child_post_resolve_promises).then(function() { return result}));') | |
w(indent_ggg_child + '} else {') | |
w(indent_gggg_child + 'resolve(result);') | |
w(indent_ggg_child + '}') | |
w(indent_gg_child + "});") | |
w(indent_g_child + '}') | |
w('') | |
w(indent_g_child + cls_name + '.prototype.save = function() {') | |
w(indent_gg_child + 'var req_defer = ' + base_factory_name + '.$q.defer();') | |
w(indent_gg_child + 'var self = this;') | |
w(indent_gg_child + 'this.pre_save().then(function(saver) {') | |
w(indent_ggg_child + "if ('url' in saver) {") | |
w(indent_gggg_child + 'var promise = ' + base_factory_name + ".$http.put(saver['url'], saver);") | |
w(indent_ggg_child + '} else {') | |
w(indent_gggg_child + "var promise = " + base_factory_name + ".$http.post('"+cls.meta['url']+"', saver);") | |
w(indent_ggg_child + '}') | |
w(indent_ggg_child + '') | |
w(indent_ggg_child + 'promise = promise.then(function(data) {') | |
w(indent_gggg_child + 'return ' + cls_name + '.post_restore(data.data,self)') | |
w(indent_ggg_child + '})') | |
w(indent_ggg_child + 'promise.catch('+base_factory_name+'.log_http_error)') | |
w(indent_ggg_child + 'req_defer.resolve(promise);') | |
w(indent_gg_child + '})') | |
w(indent_gg_child + 'return req_defer.promise;') | |
w(indent_g_child + '}') | |
w('') | |
w(indent_g_child + cls_name + '.get = function(pk,destination) {') | |
w(indent_gg_child + 'destination = destination || new ' + cls_name + '()') | |
w(indent_gg_child + 'var post_restore_intercept = function(data) {') | |
w(indent_ggg_child + 'return ' + cls_name + '.post_restore(data.data,destination);') | |
w(indent_gg_child + '}') | |
w(indent_gg_child + "var url = /^\w+$/.test(pk) ? '"+cls.meta['url'] + "'+pk+'/' : pk;") | |
w(indent_gg_child + 'var promise = '+base_factory_name+".$http.get(url)") | |
w(indent_ggg_child+ '.then(post_restore_intercept);') | |
w(indent_gg_child + 'promise.catch('+base_factory_name+'.log_http_error);') | |
w(indent_gg_child + 'return promise;') | |
w(indent_g_child + '}') | |
w('') | |
w(indent_g_child + cls_name + '.prototype.delete = function() {') | |
w(indent_gg_child + 'if (this.url) {') | |
w(indent_ggg_child + 'return '+base_factory_name+'.$http.delete(this.url);') | |
w(indent_gg_child + '} else {') | |
w(indent_ggg_child + 'var defer = '+base_factory_name+'.$q.defer();') | |
w(indent_ggg_child + 'defer.resolve();') | |
w(indent_ggg_child + 'return defer.promise;') | |
w(indent_gg_child + '}') | |
w(indent_g_child + '}') | |
w('') | |
w(indent_g_child +'return '+cls_name) | |
w(indent_child + '})();') | |
w('') | |
else: | |
child_scope = module_names + [mod_class_name] | |
child_ref = '.'.join(child_scope[-2:]) | |
w(indent_child + child_ref + '= {};') | |
w(indent_child + '(function ('+mod_class_name+') {') | |
OutputClasses(mod_class,module_names + [mod_class_name],indent_child) | |
w(indent_child + '})('+child_ref+');') | |
OutputClasses(base_module,[base_factory_name]) | |
w('})('+base_factory_name+')') | |
w('') | |
w("angular.module('app').factory('"+base_factory_name+"',[") | |
w(" '$http', 'log_http_error', '$q',") | |
w('function($http, log_http_error, $q) {') | |
def export_classes(module,print_func): | |
for mod_class_name,mod_class in module.iteritems(): | |
if isinstance(mod_class,ClassDefn): | |
print_func(base_factory_name + '.' + '.'.join(mod_class.url_name)) | |
else: | |
export_classes(mod_class,print_func) | |
w(INDENT + base_factory_name + '.$http = $http') | |
w(INDENT + base_factory_name + '.log_http_error = log_http_error') | |
w(INDENT + base_factory_name + '.$q = $q') | |
w(INDENT + 'return '+base_factory_name) | |
w('}])') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment