<s> import logging <EOL> from django . conf import settings <EOL> from django . core . urlresolvers import reverse <EOL> from django . http import Http404 <EOL> import collections <EOL> import itertools <EOL> from django import forms <EOL> from django . utils . translation import ugettext as _ <EOL> from corehq . apps . app_manager . analytics import get_exports_by_application <EOL> from corehq . apps . app_manager . dbaccessors import get_apps_in_domain , get_app <EOL> from corehq . apps . app_manager . models import Application <EOL> from corehq . form_processor . interfaces . dbaccessors import CaseAccessors <EOL> from couchforms . analytics import get_exports_by_form <EOL> from couchforms . models import XFormInstance <EOL> from dimagi . utils . decorators . memoized import memoized <EOL> ApplicationDataSource = collections . namedtuple ( '<STR_LIT>' , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:source>' ] ) <EOL> RMIDataChoice = collections . namedtuple ( '<STR_LIT>' , [ '<STR_LIT:id>' , '<STR_LIT:text>' , '<STR_LIT:data>' ] ) <EOL> AppFormRMIResponse = collections . namedtuple ( '<STR_LIT>' , [ <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' <EOL> ] ) <EOL> AppFormRMIPlaceholder = collections . namedtuple ( '<STR_LIT>' , [ <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' <EOL> ] ) <EOL> AppCaseRMIResponse = collections . namedtuple ( '<STR_LIT>' , [ <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' <EOL> ] ) <EOL> AppCaseRMIPlaceholder = collections . namedtuple ( '<STR_LIT>' , [ <EOL> '<STR_LIT>' , '<STR_LIT>' <EOL> ] ) <EOL> class ApplicationDataSourceUIHelper ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , enable_cases = True , enable_forms = True ) : <EOL> self . all_sources = { } <EOL> self . enable_cases = enable_cases <EOL> self . enable_forms = enable_forms <EOL> source_choices = [ ] <EOL> if enable_cases : <EOL> source_choices . append ( ( "<STR_LIT>" , _ ( "<STR_LIT>" ) ) ) <EOL> if enable_forms : <EOL> source_choices . append ( ( "<STR_LIT>" , _ ( "<STR_LIT>" ) ) ) <EOL> self . application_field = forms . ChoiceField ( label = _ ( '<STR_LIT>' ) , widget = forms . Select ( ) ) <EOL> if enable_cases and enable_forms : <EOL> self . source_type_field = forms . ChoiceField ( label = _ ( '<STR_LIT>' ) , <EOL> choices = source_choices , <EOL> widget = forms . Select ( choices = source_choices ) ) <EOL> else : <EOL> self . source_type_field = forms . ChoiceField ( choices = source_choices , <EOL> widget = forms . HiddenInput ( ) , <EOL> initial = source_choices [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] ) <EOL> self . source_field = forms . ChoiceField ( label = _ ( '<STR_LIT>' ) , widget = forms . Select ( ) ) <EOL> def bootstrap ( self , domain ) : <EOL> self . all_sources = get_app_sources ( domain ) <EOL> self . application_field . choices = sorted ( <EOL> [ ( app_id , source [ '<STR_LIT:name>' ] ) for app_id , source in self . all_sources . items ( ) ] , <EOL> key = lambda id_name_tuple : ( id_name_tuple [ <NUM_LIT:1> ] or '<STR_LIT>' ) . lower ( ) <EOL> ) <EOL> self . source_field . choices = [ ] <EOL> def _add_choices ( field , choices ) : <EOL> field . choices . extend ( choices ) <EOL> field . widget . choices . extend ( choices ) <EOL> if self . enable_cases : <EOL> _add_choices ( <EOL> self . source_field , <EOL> [ ( ct [ '<STR_LIT:value>' ] , ct [ '<STR_LIT:text>' ] ) for app in self . all_sources . values ( ) for ct in app [ '<STR_LIT>' ] ] <EOL> ) <EOL> if self . enable_forms : <EOL> _add_choices ( <EOL> self . source_field , <EOL> [ ( ct [ '<STR_LIT:value>' ] , ct [ '<STR_LIT:text>' ] ) for app in self . all_sources . values ( ) for ct in app [ '<STR_LIT>' ] ] <EOL> ) <EOL> self . application_field . widget . attrs = { '<STR_LIT>' : '<STR_LIT>' } <EOL> self . source_type_field . widget . attrs = { '<STR_LIT>' : '<STR_LIT>' } <EOL> self . source_field . widget . attrs = { '<STR_LIT>' : '''<STR_LIT>''' } <EOL> def get_fields ( self ) : <EOL> fields = collections . OrderedDict ( ) <EOL> fields [ '<STR_LIT>' ] = self . source_type_field <EOL> fields [ '<STR_LIT>' ] = self . application_field <EOL> fields [ '<STR_LIT:source>' ] = self . source_field <EOL> return fields <EOL> def get_app_source ( self , data_dict ) : <EOL> return ApplicationDataSource ( data_dict [ '<STR_LIT>' ] , data_dict [ '<STR_LIT>' ] , data_dict [ '<STR_LIT:source>' ] ) <EOL> def get_app_sources ( domain ) : <EOL> apps = get_apps_in_domain ( domain , include_remote = False ) <EOL> return { <EOL> app . _id : { <EOL> "<STR_LIT:name>" : app . name , <EOL> "<STR_LIT>" : [ { "<STR_LIT:text>" : t , "<STR_LIT:value>" : t } for t in app . get_case_types ( ) ] , <EOL> "<STR_LIT>" : [ <EOL> { <EOL> "<STR_LIT:text>" : u'<STR_LIT>' . format ( form . get_module ( ) . default_name ( ) , form . default_name ( ) ) , <EOL> "<STR_LIT:value>" : form . get_unique_id ( ) <EOL> } for form in app . get_forms ( ) <EOL> ] <EOL> } <EOL> for app in apps <EOL> } <EOL> class ApplicationDataRMIHelper ( object ) : <EOL> """<STR_LIT>""" <EOL> UNKNOWN_SOURCE = '<STR_LIT>' <EOL> APP_TYPE_ALL = '<STR_LIT:all>' <EOL> APP_TYPE_DELETED = '<STR_LIT>' <EOL> APP_TYPE_REMOTE = '<STR_LIT>' <EOL> APP_TYPE_NONE = '<STR_LIT>' <EOL> APP_TYPE_UNKNOWN = '<STR_LIT>' <EOL> def __init__ ( self , domain , as_dict = True , form_placeholders = None , case_placeholders = None ) : <EOL> self . domain = domain <EOL> self . as_dict = as_dict <EOL> default_form_placeholder = AppFormRMIPlaceholder ( <EOL> application = _ ( "<STR_LIT>" ) , <EOL> module = _ ( "<STR_LIT>" ) , <EOL> form = _ ( "<STR_LIT>" ) , <EOL> ) <EOL> self . form_placeholders = form_placeholders or default_form_placeholder <EOL> default_case_placeholder = AppCaseRMIPlaceholder ( <EOL> application = _ ( "<STR_LIT>" ) , <EOL> case_type = _ ( "<STR_LIT>" ) , <EOL> ) <EOL> self . case_placeholders = case_placeholders or default_case_placeholder <EOL> if self . as_dict : <EOL> self . form_placeholders = self . form_placeholders . _asdict ( ) <EOL> self . case_placeholders = self . case_placeholders . _asdict ( ) <EOL> def _get_unknown_form_possibilities ( self ) : <EOL> possibilities = collections . defaultdict ( list ) <EOL> for app in get_exports_by_application ( self . domain ) : <EOL> x = app [ '<STR_LIT:value>' ] <EOL> x [ '<STR_LIT>' ] = True <EOL> possibilities [ app [ '<STR_LIT:key>' ] [ <NUM_LIT:2> ] ] . append ( x ) <EOL> return possibilities <EOL> def _attach_unknown_suggestions ( self , unknown_forms ) : <EOL> """<STR_LIT>""" <EOL> if unknown_forms : <EOL> possibilities = self . _get_unknown_form_possibilities ( ) <EOL> class AppCache ( dict ) : <EOL> def __init__ ( self , domain ) : <EOL> super ( AppCache , self ) . __init__ ( ) <EOL> self . domain = domain <EOL> def __getitem__ ( self , item ) : <EOL> if item not in self : <EOL> try : <EOL> self [ item ] = get_app ( app_id = item , domain = self . domain ) <EOL> except Http404 : <EOL> pass <EOL> return super ( AppCache , self ) . __getitem__ ( item ) <EOL> app_cache = AppCache ( self . domain ) <EOL> for form in unknown_forms : <EOL> app = None <EOL> if form [ '<STR_LIT>' ] [ '<STR_LIT:id>' ] : <EOL> try : <EOL> app = app_cache [ form [ '<STR_LIT>' ] [ '<STR_LIT:id>' ] ] <EOL> form [ '<STR_LIT>' ] = True <EOL> except KeyError : <EOL> form [ '<STR_LIT>' ] = True <EOL> form [ '<STR_LIT>' ] = possibilities [ form [ '<STR_LIT>' ] ] <EOL> if form [ '<STR_LIT>' ] : <EOL> form [ '<STR_LIT>' ] = True <EOL> else : <EOL> if app . domain != self . domain : <EOL> logging . error ( "<STR_LIT>" % app . get_id ) <EOL> else : <EOL> if app . copy_of : <EOL> try : <EOL> app = app_cache [ app . copy_of ] <EOL> form [ '<STR_LIT>' ] = { '<STR_LIT:id>' : app . get_id , '<STR_LIT:name>' : app . name } <EOL> except KeyError : <EOL> form [ '<STR_LIT>' ] = { '<STR_LIT:id>' : app . copy_of , '<STR_LIT:name>' : '<STR_LIT:?>' } <EOL> if app . is_deleted ( ) : <EOL> form [ '<STR_LIT>' ] = { '<STR_LIT:id>' : app . get_id } <EOL> try : <EOL> app_forms = app . get_xmlns_map ( ) [ form [ '<STR_LIT>' ] ] <EOL> except AttributeError : <EOL> app_forms = None <EOL> form [ '<STR_LIT>' ] = True <EOL> if app_forms : <EOL> app_form = app_forms [ <NUM_LIT:0> ] <EOL> if app_form . doc_type == '<STR_LIT>' : <EOL> form [ '<STR_LIT>' ] = True <EOL> else : <EOL> app_module = app_form . get_module ( ) <EOL> form [ '<STR_LIT>' ] = app_module <EOL> form [ '<STR_LIT>' ] = app_form <EOL> form [ '<STR_LIT>' ] = False <EOL> if not form . get ( '<STR_LIT>' ) and not form . get ( '<STR_LIT>' ) : <EOL> form [ '<STR_LIT>' ] = True <EOL> if app : <EOL> form [ '<STR_LIT>' ] = { '<STR_LIT:id>' : app . get_id , '<STR_LIT:name>' : app . name , '<STR_LIT>' : app . langs } <EOL> else : <EOL> form [ '<STR_LIT>' ] = possibilities [ form [ '<STR_LIT>' ] ] <EOL> if form [ '<STR_LIT>' ] : <EOL> form [ '<STR_LIT>' ] = True <EOL> else : <EOL> form [ '<STR_LIT>' ] = True <EOL> return unknown_forms <EOL> @ staticmethod <EOL> def _sorkey_form ( form ) : <EOL> app_id = form [ '<STR_LIT>' ] [ '<STR_LIT:id>' ] <EOL> if form . get ( '<STR_LIT>' , False ) : <EOL> order = <NUM_LIT:0> if not form . get ( '<STR_LIT>' ) else <NUM_LIT:1> <EOL> app_name = form [ '<STR_LIT>' ] [ '<STR_LIT:name>' ] <EOL> module = form . get ( '<STR_LIT>' ) <EOL> if module : <EOL> module_id = module [ '<STR_LIT:id>' ] if '<STR_LIT:id>' in module else module . id <EOL> else : <EOL> module_id = - <NUM_LIT:1> if form . get ( '<STR_LIT>' ) else <NUM_LIT:1000> <EOL> app_form = form . get ( '<STR_LIT>' ) <EOL> if app_form : <EOL> form_id = app_form [ '<STR_LIT:id>' ] if '<STR_LIT:id>' in app_form else app_form . id <EOL> else : <EOL> form_id = - <NUM_LIT:1> <EOL> return ( order , app_name , app_id , module_id , form_id ) <EOL> else : <EOL> form_xmlns = form [ '<STR_LIT>' ] <EOL> return ( <NUM_LIT:2> , form_xmlns , app_id ) <EOL> @ property <EOL> @ memoized <EOL> def _all_forms ( self ) : <EOL> forms = [ ] <EOL> unknown_forms = [ ] <EOL> for f in get_exports_by_form ( self . domain ) : <EOL> form = f [ '<STR_LIT:value>' ] <EOL> if form . get ( '<STR_LIT>' ) and not form . get ( '<STR_LIT>' ) : <EOL> continue <EOL> if '<STR_LIT>' in form : <EOL> form [ '<STR_LIT>' ] = True <EOL> forms . append ( form ) <EOL> else : <EOL> app_id = f [ '<STR_LIT:key>' ] [ <NUM_LIT:1> ] or '<STR_LIT>' <EOL> form [ '<STR_LIT>' ] = { <EOL> '<STR_LIT:id>' : app_id <EOL> } <EOL> form [ '<STR_LIT>' ] = False <EOL> form [ '<STR_LIT>' ] = True <EOL> unknown_forms . append ( form ) <EOL> forms . extend ( self . _attach_unknown_suggestions ( unknown_forms ) ) <EOL> return sorted ( forms , key = self . _sorkey_form ) <EOL> @ property <EOL> @ memoized <EOL> def _no_app_forms ( self ) : <EOL> return filter ( lambda f : not f . get ( '<STR_LIT>' , False ) , self . _all_forms ) <EOL> @ property <EOL> @ memoized <EOL> def _remote_app_forms ( self ) : <EOL> return filter ( lambda f : f . get ( '<STR_LIT>' , False ) and f . get ( '<STR_LIT>' , False ) , self . _all_forms ) <EOL> @ property <EOL> @ memoized <EOL> def _deleted_app_forms ( self ) : <EOL> return filter ( <EOL> lambda f : f . get ( '<STR_LIT>' , False ) and f . get ( '<STR_LIT>' ) and not f . get ( '<STR_LIT>' , False ) , <EOL> self . _all_forms <EOL> ) <EOL> @ property <EOL> @ memoized <EOL> def _available_app_forms ( self ) : <EOL> return filter ( <EOL> lambda f : f . get ( '<STR_LIT>' , False ) and not f . get ( '<STR_LIT>' ) and not f . get ( '<STR_LIT>' , False ) , <EOL> self . _all_forms <EOL> ) <EOL> @ property <EOL> @ memoized <EOL> def _unknown_forms ( self ) : <EOL> return itertools . chain ( self . _deleted_app_forms , self . _remote_app_forms , self . _no_app_forms ) <EOL> def _get_app_type_choices ( self , as_dict = True ) : <EOL> choices = [ ( _ ( "<STR_LIT>" ) , self . APP_TYPE_ALL ) ] <EOL> if self . _remote_app_forms or self . _deleted_app_forms : <EOL> choices . append ( ( _ ( "<STR_LIT>" ) , self . APP_TYPE_UNKNOWN ) ) <EOL> choices = map ( lambda c : RMIDataChoice ( id = c [ <NUM_LIT:1> ] , text = c [ <NUM_LIT:0> ] , data = { } ) , choices ) <EOL> if as_dict : <EOL> choices = map ( lambda c : c . _asdict ( ) , choices ) <EOL> return choices <EOL> @ staticmethod <EOL> def _get_unique_choices ( choices ) : <EOL> final_choices = collections . defaultdict ( list ) <EOL> for k , val_list in choices . items ( ) : <EOL> new_val_ids = [ ] <EOL> final_choices [ k ] = [ ] <EOL> for v in val_list : <EOL> if v . id not in new_val_ids : <EOL> new_val_ids . append ( v . id ) <EOL> final_choices [ k ] . append ( v ) <EOL> return final_choices <EOL> def _get_applications_by_type ( self , as_dict = True ) : <EOL> apps_by_type = ( <EOL> ( self . APP_TYPE_ALL , self . _available_app_forms ) , <EOL> ( self . APP_TYPE_UNKNOWN , self . _unknown_forms ) <EOL> ) <EOL> _app_fmt = lambda c : ( c [ <NUM_LIT:0> ] , map ( lambda f : RMIDataChoice ( <EOL> f [ '<STR_LIT>' ] [ '<STR_LIT:id>' ] if f . get ( '<STR_LIT>' , False ) else self . UNKNOWN_SOURCE , <EOL> f [ '<STR_LIT>' ] [ '<STR_LIT:name>' ] if f . get ( '<STR_LIT>' , False ) else _ ( "<STR_LIT>" ) , <EOL> f <EOL> ) , c [ <NUM_LIT:1> ] ) ) <EOL> apps_by_type = map ( _app_fmt , apps_by_type ) <EOL> apps_by_type = dict ( apps_by_type ) <EOL> apps_by_type = self . _get_unique_choices ( apps_by_type ) <EOL> for app in apps_by_type [ self . APP_TYPE_DELETED ] : <EOL> app . data [ '<STR_LIT>' ] = reverse ( '<STR_LIT>' , args = [ self . domain , app . id ] ) <EOL> if as_dict : <EOL> apps_by_type = self . _map_chosen_by_choice_as_dict ( apps_by_type ) <EOL> return apps_by_type <EOL> @ staticmethod <EOL> def _map_chosen_by_choice_as_dict ( chosen_by_choice ) : <EOL> for k , v in chosen_by_choice . items ( ) : <EOL> chosen_by_choice [ k ] = map ( lambda f : f . _asdict ( ) , v ) <EOL> return chosen_by_choice <EOL> @ staticmethod <EOL> def _get_item_name ( item , has_app , app_lang , default_name ) : <EOL> item_name = None <EOL> if has_app and item is not None : <EOL> item_name = item [ '<STR_LIT:name>' ] . get ( app_lang ) or item [ '<STR_LIT:name>' ] . get ( '<STR_LIT>' ) <EOL> return item_name or default_name <EOL> def _get_modules_and_forms ( self , as_dict = True ) : <EOL> modules_by_app = collections . defaultdict ( list ) <EOL> forms_by_app_by_module = { } <EOL> for form in self . _all_forms : <EOL> has_app = form . get ( '<STR_LIT>' , False ) <EOL> app_lang = form [ '<STR_LIT>' ] [ '<STR_LIT>' ] [ <NUM_LIT:0> ] if '<STR_LIT>' in form [ '<STR_LIT>' ] else '<STR_LIT>' <EOL> app_id = form [ '<STR_LIT>' ] [ '<STR_LIT:id>' ] if has_app else self . UNKNOWN_SOURCE <EOL> module = form . get ( '<STR_LIT>' ) <EOL> module_id = ( module [ '<STR_LIT:id>' ] if has_app and module is not None <EOL> else self . UNKNOWN_SOURCE ) <EOL> module_name = self . _get_item_name ( <EOL> module , has_app , app_lang , _ ( "<STR_LIT>" ) <EOL> ) <EOL> form_xmlns = form [ '<STR_LIT>' ] <EOL> form_name = form_xmlns <EOL> if not form . get ( '<STR_LIT>' , False ) : <EOL> form_name = self . _get_item_name ( <EOL> form . get ( '<STR_LIT>' ) , has_app , app_lang , <EOL> "<STR_LIT>" . format ( form_xmlns ) <EOL> ) <EOL> module_choice = RMIDataChoice ( <EOL> module_id , <EOL> module_name , <EOL> form <EOL> ) <EOL> form_choice = RMIDataChoice ( <EOL> form_xmlns , <EOL> form_name , <EOL> form <EOL> ) <EOL> if as_dict : <EOL> form_choice = form_choice . _asdict ( ) <EOL> if app_id not in forms_by_app_by_module : <EOL> forms_by_app_by_module [ app_id ] = collections . defaultdict ( list ) <EOL> modules_by_app [ app_id ] . append ( module_choice ) <EOL> forms_by_app_by_module [ app_id ] [ module_id ] . append ( form_choice ) <EOL> modules_by_app = self . _get_unique_choices ( modules_by_app ) <EOL> if as_dict : <EOL> modules_by_app = self . _map_chosen_by_choice_as_dict ( modules_by_app ) <EOL> return modules_by_app , forms_by_app_by_module <EOL> def get_form_rmi_response ( self ) : <EOL> """<STR_LIT>""" <EOL> modules_by_app , forms_by_app_by_module = self . _get_modules_and_forms ( self . as_dict ) <EOL> response = AppFormRMIResponse ( <EOL> app_types = self . _get_app_type_choices ( self . as_dict ) , <EOL> apps_by_type = self . _get_applications_by_type ( self . as_dict ) , <EOL> modules_by_app = modules_by_app , <EOL> forms_by_app_by_module = forms_by_app_by_module , <EOL> placeholders = self . form_placeholders , <EOL> ) <EOL> if self . as_dict : <EOL> response = response . _asdict ( ) <EOL> return response <EOL> def _get_cases_for_apps ( self , apps_by_type , as_dict = True ) : <EOL> used_case_types = set ( ) <EOL> case_types_by_app = collections . defaultdict ( list ) <EOL> for app_type , apps in apps_by_type . items ( ) : <EOL> for app_choice in apps : <EOL> if not app_choice . id == self . UNKNOWN_SOURCE : <EOL> app = get_app ( self . domain , app_choice . id ) <EOL> case_types = [ ] <EOL> if hasattr ( app , '<STR_LIT>' ) : <EOL> case_types = set ( [ <EOL> module . case_type <EOL> for module in app . modules if module . case_type <EOL> ] ) <EOL> used_case_types = used_case_types . union ( case_types ) <EOL> case_types = map ( lambda c : RMIDataChoice ( <EOL> id = c , <EOL> text = c , <EOL> data = app_choice . data <EOL> ) , case_types ) <EOL> if as_dict : <EOL> case_types = map ( lambda c : c . _asdict ( ) , case_types ) <EOL> case_types_by_app [ app_choice . id ] = case_types <EOL> else : <EOL> all_case_types = CaseAccessors ( self . domain ) . get_case_types ( ) <EOL> unknown_case_types = all_case_types . difference ( used_case_types ) <EOL> unknown_case_types = map ( lambda c : RMIDataChoice ( <EOL> id = c , <EOL> text = c , <EOL> data = { <EOL> '<STR_LIT>' : True , <EOL> } <EOL> ) , unknown_case_types ) <EOL> if as_dict : <EOL> unknown_case_types = map ( lambda c : c . _asdict ( ) , unknown_case_types ) <EOL> case_types_by_app [ self . UNKNOWN_SOURCE ] = unknown_case_types <EOL> return case_types_by_app <EOL> def get_case_rmi_response ( self ) : <EOL> """<STR_LIT>""" <EOL> apps_by_type = self . _get_applications_by_type ( as_dict = False ) <EOL> case_types_by_app = self . _get_cases_for_apps ( apps_by_type , self . as_dict ) <EOL> if self . as_dict : <EOL> apps_by_type = self . _map_chosen_by_choice_as_dict ( apps_by_type ) <EOL> response = AppCaseRMIResponse ( <EOL> app_types = self . _get_app_type_choices ( ) , <EOL> apps_by_type = apps_by_type , <EOL> case_types_by_app = case_types_by_app , <EOL> placeholders = self . case_placeholders <EOL> ) <EOL> if self . as_dict : <EOL> response = response . _asdict ( ) <EOL> return response </s>
