Example #1
0
def case_list(request, domain):
    
    apps = filter(lambda app: app.doc_type == "Application",
                  ApplicationBase.view('app_manager/applications_brief', 
                                       startkey=[domain], endkey=[domain, {}]))
    
    user_id = request.REQUEST.get("user_id", request.couch_user.get_id)
    app_id = request.REQUEST.get("app_id", "")
    module_id = int(request.REQUEST.get("module_id", "0"))
    language = request.REQUEST.get("language", "en")
    
    if not app_id and apps:
        app_id = apps[0].get_id
    
    if app_id:
        app = Application.get(app_id)
        case_short = app.modules[module_id].get_detail("case_short")
        case_long = app.modules[module_id].get_detail("case_long")
    else:
        case_short=""
        case_long=""
    
    return render_to_response(request, "cloudcare/list_cases.html", 
                              {"domain": domain,
                               "language": language,
                               "user_id": user_id,
                               "apps": apps,
                               "case_short": json.dumps(case_short._doc),
                               "case_long": json.dumps(case_long._doc),
                               "cases": json.dumps(get_owned_cases(domain, user_id),
                                                   default=json_handler)})
Example #2
0
 def _app_latest_build_json(app_id):
     build = ApplicationBase.view('app_manager/saved_app',
                                  startkey=[domain, app_id, {}],
                                  endkey=[domain, app_id],
                                  descending=True,
                                  limit=1).one()
     return get_app_json(build) if build else None
Example #3
0
 def _app_latest_build_json(app_id):
     build = ApplicationBase.view('app_manager/saved_app',
                                  startkey=[domain, app_id, {}],
                                  endkey=[domain, app_id],
                                  descending=True,
                                  limit=1).one()
     return build._doc if build else None
Example #4
0
def app_list(request, domain, urlPath):
    preview = string_to_boolean(request.REQUEST.get("preview", "false"))
    language = request.couch_user.language or "en"
    
    def _app_latest_build_json(app_id):
        build = ApplicationBase.view('app_manager/saved_app',
                                     startkey=[domain, app["_id"], {}],
                                     endkey=[domain, app["_id"]],
                                     descending=True,
                                     limit=1).one()
        return build._doc if build else None
                                     
    if not preview:
        apps = get_cloudcare_apps(domain)
        # replace the apps with the last build of each app
        apps = [_app_latest_build_json(app["_id"])for app in apps]
    
    else:
        apps = ApplicationBase.view('app_manager/applications_brief', startkey=[domain], endkey=[domain, {}])
        apps = [app._doc for app in apps if app and app.application_version == "2.0"]
    
    # trim out empty apps
    apps = filter(lambda app: app, apps)
    return render_to_response(request, "cloudcare/cloudcare_home.html", 
                              {"domain": domain,
                               "language": language,
                               "apps": json.dumps(apps),
                               "apps_raw": apps,
                               "preview": preview,
                               "maps_api_key": settings.GMAPS_API_KEY })
Example #5
0
def get_form_list(domain):
    form_list = []
    for app in ApplicationBase.view("app_manager/applications_brief",
                                    startkey=[domain],
                                    endkey=[domain, {}]):
        latest_app = get_app(domain, app._id, latest=True)
        if latest_app.doc_type == "Application":
            lang = latest_app.langs[0]
            for m in latest_app.get_modules():
                for f in m.get_forms():
                    try:
                        module_name = m.name[lang]
                    except Exception:
                        module_name = m.name.items()[0][1]
                    try:
                        form_name = f.name[lang]
                    except Exception:
                        form_name = f.name.items()[0][1]
                    form_list.append({
                        "code":
                        f.unique_id,
                        "name":
                        app.name + "/" + module_name + "/" + form_name
                    })
    return form_list
Example #6
0
def get_form_list(domain):
    form_list = []
    for app in ApplicationBase.view("app_manager/applications_brief", startkey=[domain], endkey=[domain, {}]):
        latest_app = get_app(domain, app._id, latest=True)
        if latest_app.doc_type == "Application":
            for m in latest_app.get_modules():
                for f in m.get_forms():
                    form_list.append({"code": f.unique_id, "name": f.full_path_name})
    return form_list
Example #7
0
def all_commcare_settings(request):
    apps = ApplicationBase.view("app_manager/applications_brief", include_docs=True)
    filters = set()
    for param in request.GET:
        s_type, name = param.split(".")
        value = request.GET.get(param)
        filters.add((s_type, name, value))

    def app_filter(settings):
        for s_type, name, value in filters:
            if settings[s_type].get(name) != value:
                return False
        return True

    settings_list = [s for s in (get_settings_values(app) for app in apps) if app_filter(s)]
    return json_response(settings_list)
Example #8
0
def get_form_list(domain):
    form_list = []
    for app in ApplicationBase.view("app_manager/applications_brief", startkey=[domain], endkey=[domain, {}]):
        latest_app = get_app(domain, app._id, latest=True)
        if latest_app.doc_type == "Application":
            lang = latest_app.langs[0]
            for m in latest_app.get_modules():
                for f in m.get_forms():
                    try:
                        module_name = m.name[lang]
                    except Exception:
                        module_name = m.name.items()[0][1]
                    try:
                        form_name = f.name[lang]
                    except Exception:
                        form_name = f.name.items()[0][1]
                    form_list.append({"code" :  f.unique_id, "name" : app.name + "/" + module_name + "/" + form_name})
    return form_list
Example #9
0
def all_commcare_settings(request):
    apps = ApplicationBase.view('app_manager/applications_brief',
                                include_docs=True)
    filters = set()
    for param in request.GET:
        s_type, name = param.split('.')
        value = request.GET.get(param)
        filters.add((s_type, name, value))

    def app_filter(settings):
        for s_type, name, value in filters:
            if settings[s_type].get(name) != value:
                return False
        return True

    settings_list = [s for s in (get_settings_values(app) for app in apps)
                     if app_filter(s)]
    return json_response(settings_list)
Example #10
0
def get_cloudcare_apps(domain):
    return map(lambda app: app._doc,
               ApplicationBase.view('cloudcare/cloudcare_apps', 
                                    startkey=[domain], endkey=[domain, {}]))
Example #11
0
def excel_config(request, domain):
    if request.method != 'POST':
        return HttpResponseRedirect(base.ImportCases.get_url(domain=domain))

    if not request.FILES:
        return render_error(request, domain,
                            'Please choose an Excel file to import.')

    named_columns = request.POST.get('named_columns') == "on"
    uploaded_file_handle = request.FILES['file']

    extension = os.path.splitext(
        uploaded_file_handle.name)[1][1:].strip().lower()

    # NOTE: We may not always be able to reference files from subsequent
    # views if your worker changes, so we have to store it elsewhere
    # using the soil framework.

    if extension not in importer_util.ExcelFile.ALLOWED_EXTENSIONS:
        return render_error(
            request, domain,
            'The Excel file you chose could not be processed. '
            'Please check that it is saved as a Microsoft '
            'Excel 97/2000 .xls file.')

    # stash content in the default storage for subsequent views
    file_ref = expose_download(uploaded_file_handle.read(), expiry=1 * 60 * 60)
    request.session[EXCEL_SESSION_ID] = file_ref.download_id
    spreadsheet = importer_util.get_spreadsheet(file_ref, named_columns)

    if not spreadsheet:
        return _spreadsheet_expired(request, domain)

    columns = spreadsheet.get_header_columns()
    row_count = spreadsheet.get_num_rows()

    if row_count == 0:
        return render_error(
            request, domain, 'Your spreadsheet is empty. '
            'Please try again with a different spreadsheet.')

    case_types_from_apps = []
    # load types from all modules
    for row in ApplicationBase.view('app_manager/types_by_module',
                                    reduce=True,
                                    group=True,
                                    startkey=[domain],
                                    endkey=[domain, {}]).all():
        if not row['key'][1] in case_types_from_apps:
            case_types_from_apps.append(row['key'][1])

    case_types_from_cases = []
    # load types from all case records
    for row in CommCareCase.view('hqcase/types_by_domain',
                                 reduce=True,
                                 group=True,
                                 startkey=[domain],
                                 endkey=[domain, {}]).all():
        if row['key'][1] and not row['key'][1] in case_types_from_cases:
            case_types_from_cases.append(row['key'][1])

    # for this we just want cases that have data but aren't being used anymore
    case_types_from_cases = filter(lambda x: x not in case_types_from_apps,
                                   case_types_from_cases)

    if len(case_types_from_apps) == 0 and len(case_types_from_cases) == 0:
        return render_error(
            request, domain,
            'No cases have been submitted to this domain and there are no '
            'applications yet. You cannot import case details from an Excel '
            'file until you have existing cases or applications.')

    return render(
        request, "importer/excel_config.html", {
            'named_columns': named_columns,
            'columns': columns,
            'case_types_from_cases': case_types_from_cases,
            'case_types_from_apps': case_types_from_apps,
            'domain': domain,
            'report': {
                'name': 'Import: Configuration'
            },
            'slug': base.ImportCases.slug
        })
Example #12
0
def cloudcare_main(request, domain, urlPath):
    try:
        preview = string_to_boolean(request.REQUEST.get("preview", "false"))
    except ValueError:
        # this is typically only set at all if it's intended to be true so this
        # is a reasonable default for "something went wrong"
        preview = True

    app_access = ApplicationAccess.get_by_domain(domain)
    
    def _app_latest_build_json(app_id):
        build = ApplicationBase.view('app_manager/saved_app',
                                     startkey=[domain, app_id, {}],
                                     endkey=[domain, app_id],
                                     descending=True,
                                     limit=1).one()
        return get_app_json(build) if build else None

    if not preview:
        apps = get_cloudcare_apps(domain)
        # replace the apps with the last build of each app
        apps = [_app_latest_build_json(app["_id"]) for app in apps]
    else:
        apps = ApplicationBase.view('app_manager/applications_brief', startkey=[domain], endkey=[domain, {}])
        apps = [get_app_json(app) for app in apps if app and app.application_version == V2]

    # trim out empty apps
    apps = filter(lambda app: app, apps)
    apps = filter(lambda app: app_access.user_can_access_app(request.couch_user, app), apps)
    
    def _default_lang():
        if apps:
            # unfortunately we have to go back to the DB to find this
            return Application.get(apps[0]["_id"]).build_langs[0]
        else:
            return "en"

    # default language to user's preference, followed by 
    # first app's default, followed by english
    language = request.couch_user.language or _default_lang()
    
    def _url_context():
        # given a url path, returns potentially the app and case, if they're
        # selected. the front end optimizes with these to avoid excess server
        # calls

        # there's an annoying dependency between this logic and backbone's
        # url routing that seems hard to solve well. this needs to be synced
        # with apps.js if anything changes

        # for apps anything with "view/app/" works

        # for cases it will be:
        # "view/:app/:module/:form/case/:case/"
        
        # could use regex here but this is actually simpler with the potential
        # absence of a trailing slash
        split = urlPath.split('/')
        app_id = split[1] if len(split) >= 2 else None
        case_id = split[5] if len(split) >= 6 else None
        
        app = None
        if app_id:
            if app_id in [a['_id'] for a in apps]:
                app = look_up_app_json(domain, app_id)
            else:
                messages.info(request, _("That app is no longer valid. Try using the "
                                         "navigation links to select an app."))
        if app is None and len(apps) == 1:
            app = look_up_app_json(domain, apps[0]['_id'])

        def _get_case(domain, case_id):
            case = CommCareCase.get(case_id)
            assert case.domain == domain, "case %s not in %s" % (case_id, domain)
            return case.get_json()
        
        case = _get_case(domain, case_id) if case_id else None
        return {
            "app": app,
            "case": case
        }

    context = {
       "domain": domain,
       "language": language,
       "apps": apps,
       "apps_raw": apps,
       "preview": preview,
       "maps_api_key": settings.GMAPS_API_KEY
    }
    context.update(_url_context())
    return render(request, "cloudcare/cloudcare_home.html", context)
Example #13
0
def get_cloudcare_apps(domain):
    return map(
        lambda app: app._doc,
        ApplicationBase.view('cloudcare/cloudcare_apps',
                             startkey=[domain],
                             endkey=[domain, {}]))
Example #14
0
def cloudcare_main(request, domain, urlPath):
    try:
        preview = string_to_boolean(request.REQUEST.get("preview", "false"))
    except ValueError:
        # this is typically only set at all if it's intended to be true so this
        # is a reasonable default for "something went wrong"
        preview = True

    app_access = ApplicationAccess.get_by_domain(domain)

    if not preview:
        apps = get_cloudcare_apps(domain)
        if request.project.use_cloudcare_releases:
            # replace the apps with the last starred build of each app, removing the ones that aren't starred
            apps = filter(lambda app: app.is_released, [get_app(domain, app['_id'], latest=True) for app in apps])
            # convert to json
            apps = [get_app_json(app) for app in apps]
        else:
            # legacy functionality - use the latest build regardless of stars
            apps = [get_app_json(ApplicationBase.get_latest_build(domain, app['_id'])) for app in apps]

    else:
        apps = ApplicationBase.view('app_manager/applications_brief', startkey=[domain], endkey=[domain, {}])
        apps = [get_app_json(app) for app in apps if app and app.application_version == V2]

    # trim out empty apps
    apps = filter(lambda app: app, apps)
    apps = filter(lambda app: app_access.user_can_access_app(request.couch_user, app), apps)
    
    def _default_lang():
        if apps:
            # unfortunately we have to go back to the DB to find this
            return Application.get(apps[0]["_id"]).build_langs[0]
        else:
            return "en"

    # default language to user's preference, followed by 
    # first app's default, followed by english
    language = request.couch_user.language or _default_lang()
    
    def _url_context():
        # given a url path, returns potentially the app, parent, and case, if
        # they're selected. the front end optimizes with these to avoid excess
        # server calls

        # there's an annoying dependency between this logic and backbone's
        # url routing that seems hard to solve well. this needs to be synced
        # with apps.js if anything changes

        # for apps anything with "view/app/" works

        # for cases it will be:
        # "view/:app/:module/:form/case/:case/"

        # if there are parent cases, it will be:
        # "view/:app/:module/:form/parent/:parent/case/:case/
        
        # could use regex here but this is actually simpler with the potential
        # absence of a trailing slash
        split = urlPath.split('/')
        app_id = split[1] if len(split) >= 2 else None

        if len(split) >= 5 and split[4] == "parent":
            parent_id = split[5]
            case_id = split[7] if len(split) >= 7 else None
        else:
            parent_id = None
            case_id = split[5] if len(split) >= 6 else None

        app = None
        if app_id:
            if app_id in [a['_id'] for a in apps]:
                app = look_up_app_json(domain, app_id)
            else:
                messages.info(request, _("That app is no longer valid. Try using the "
                                         "navigation links to select an app."))
        if app is None and len(apps) == 1:
            app = look_up_app_json(domain, apps[0]['_id'])

        def _get_case(domain, case_id):
            case = CommCareCase.get(case_id)
            assert case.domain == domain, "case %s not in %s" % (case_id, domain)
            return case.get_json()

        case = _get_case(domain, case_id) if case_id else None
        if parent_id is None and case is not None:
            parent_id = case.get('indices',{}).get('parent', {}).get('case_id', None)
        parent = _get_case(domain, parent_id) if parent_id else None

        return {
            "app": app,
            "case": case,
            "parent": parent
        }

    context = {
       "domain": domain,
       "language": language,
       "apps": apps,
       "apps_raw": apps,
       "preview": preview,
       "maps_api_key": settings.GMAPS_API_KEY,
       'offline_enabled': toggles.OFFLINE_CLOUDCARE.enabled(request.user.username),
       'sessions_enabled': request.couch_user.is_commcare_user(),
       'use_cloudcare_releases': request.project.use_cloudcare_releases,
    }
    context.update(_url_context())
    return render(request, "cloudcare/cloudcare_home.html", context)
Example #15
0
 def applications(self):
     from corehq.apps.app_manager.models import ApplicationBase
     return ApplicationBase.view('app_manager/applications_brief',
                                 startkey=[self.name],
                                 endkey=[self.name, {}]).all()
Example #16
0
 def applications(self):
     from corehq.apps.app_manager.models import ApplicationBase
     return ApplicationBase.view('app_manager/applications_brief',
                                 startkey=[self.name],
                                 endkey=[self.name, {}]).all()
Example #17
0
def excel_config(request, domain):
    """
    Step one of three.

    This is the initial post when the user uploads the excel file

    named_columns:
        Whether or not the first row of the excel sheet contains
        header strings for the columns. This defaults to True and
        should potentially not be an option as it is always used
        due to how important it is to see column headers
        in the rest of the importer.
    """
    if request.method != 'POST':
        return HttpResponseRedirect(base.ImportCases.get_url(domain=domain))

    if not request.FILES:
        return render_error(request, domain, 'Please choose an Excel file to import.')

    named_columns = request.POST.get('named_columns') == "on"
    uploaded_file_handle = request.FILES['file']

    extension = os.path.splitext(uploaded_file_handle.name)[1][1:].strip().lower()

    # NOTE: We may not always be able to reference files from subsequent
    # views if your worker changes, so we have to store it elsewhere
    # using the soil framework.

    if extension not in importer_util.ExcelFile.ALLOWED_EXTENSIONS:
        return render_error(request, domain,
                            'The Excel file you chose could not be processed. '
                            'Please check that it is saved as a Microsoft '
                            'Excel 97/2000 .xls file.')

    # stash content in the default storage for subsequent views
    file_ref = expose_cached_download(
        uploaded_file_handle.read(),
        expiry=1*60*60,
        file_extension=file_extention_from_filename(uploaded_file_handle.name),
    )
    request.session[EXCEL_SESSION_ID] = file_ref.download_id
    spreadsheet = importer_util.get_spreadsheet(file_ref, named_columns)

    if not spreadsheet:
        return _spreadsheet_expired(request, domain)

    columns = spreadsheet.get_header_columns()
    row_count = spreadsheet.get_num_rows()

    if row_count == 0:
        return render_error(request, domain,
                            'Your spreadsheet is empty. '
                            'Please try again with a different spreadsheet.')

    case_types_from_apps = []
    # load types from all modules
    for row in ApplicationBase.view(
        'app_manager/types_by_module',
        reduce=True,
        group=True,
        startkey=[domain],
        endkey=[domain, {}]
    ).all():
        if not row['key'][1] in case_types_from_apps:
            case_types_from_apps.append(row['key'][1])

    case_types_from_cases = get_case_types_for_domain(domain)
    # for this we just want cases that have data but aren't being used anymore
    case_types_from_cases = filter(lambda x: x not in case_types_from_apps, case_types_from_cases)

    if len(case_types_from_apps) == 0 and len(case_types_from_cases) == 0:
        return render_error(
            request,
            domain,
            'No cases have been submitted to this domain and there are no '
            'applications yet. You cannot import case details from an Excel '
            'file until you have existing cases or applications.'
        )

    return render(
        request,
        "importer/excel_config.html", {
            'named_columns': named_columns,
            'columns': columns,
            'case_types_from_cases': case_types_from_cases,
            'case_types_from_apps': case_types_from_apps,
            'domain': domain,
            'report': {
                'name': 'Import: Configuration'
            },
            'slug': base.ImportCases.slug
        }
    )
Example #18
0
def cloudcare_main(request, domain, urlPath):
    preview = string_to_boolean(request.REQUEST.get("preview", "false"))
    app_access = ApplicationAccess.get_by_domain(domain)

    def _app_latest_build_json(app_id):
        build = ApplicationBase.view('app_manager/saved_app',
                                     startkey=[domain, app_id, {}],
                                     endkey=[domain, app_id],
                                     descending=True,
                                     limit=1).one()
        return build._doc if build else None

    if not preview:
        apps = get_cloudcare_apps(domain)
        # replace the apps with the last build of each app
        apps = [_app_latest_build_json(app["_id"]) for app in apps]

    else:
        apps = ApplicationBase.view('app_manager/applications_brief',
                                    startkey=[domain],
                                    endkey=[domain, {}])
        apps = [
            app._doc for app in apps
            if app and app.application_version == "2.0"
        ]

    # trim out empty apps
    apps = filter(lambda app: app, apps)
    apps = filter(
        lambda app: app_access.user_can_access_app(request.couch_user, app),
        apps)

    def _default_lang():
        if apps:
            # unfortunately we have to go back to the DB to find this
            return Application.get(apps[0]["_id"]).build_langs[0]
        else:
            return "en"

    # default language to user's preference, followed by
    # first app's default, followed by english
    language = request.couch_user.language or _default_lang()

    def _url_context():
        # given a url path, returns potentially the app and case, if they're
        # selected. the front end optimizes with these to avoid excess server
        # calls

        # there's an annoying dependency between this logic and backbone's
        # url routing that seems hard to solve well. this needs to be synced
        # with apps.js if anything changes

        # for apps anything with "view/app/" works

        # for cases it will be:
        # "view/:app/:module/:form/case/:case/"

        # could use regex here but this is actually simpler with the potential
        # absence of a trailing slash
        split = urlPath.split('/')
        app_id = split[1] if len(split) >= 2 else None
        case_id = split[5] if len(split) >= 6 else None

        app = None
        if app_id:
            if app_id in [a['_id'] for a in apps]:
                app = get_app(domain, app_id)
            else:
                messages.info(
                    request,
                    _("That app is no longer valid. Try using the "
                      "navigation links to select an app."))
        if app == None and len(apps) == 1:
            app = get_app(domain, apps[0]['_id'])

        def _get_case(domain, case_id):
            case = CommCareCase.get(case_id)
            assert case.domain == domain, "case %s not in %s" % (case_id,
                                                                 domain)
            return case.get_json()

        case = _get_case(domain, case_id) if case_id else None
        return {"app": app, "case": case}
Example #19
0
def cloudcare_main(request, domain, urlPath):
    try:
        preview = string_to_boolean(request.REQUEST.get("preview", "false"))
    except ValueError:
        # this is typically only set at all if it's intended to be true so this
        # is a reasonable default for "something went wrong"
        preview = True

    app_access = ApplicationAccess.get_by_domain(domain)

    if not preview:
        apps = get_cloudcare_apps(domain)
        if request.project.use_cloudcare_releases:
            # replace the apps with the last starred build of each app, removing the ones that aren't starred
            apps = filter(
                lambda app: app.is_released,
                [get_app(domain, app['_id'], latest=True) for app in apps])
            # convert to json
            apps = [get_app_json(app) for app in apps]
        else:
            # legacy functionality - use the latest build regardless of stars
            apps = [
                get_app_json(
                    ApplicationBase.get_latest_build(domain, app['_id']))
                for app in apps
            ]

    else:
        apps = ApplicationBase.view('app_manager/applications_brief',
                                    startkey=[domain],
                                    endkey=[domain, {}])
        apps = [
            get_app_json(app) for app in apps
            if app and app.application_version == V2
        ]

    # trim out empty apps
    apps = filter(lambda app: app, apps)
    apps = filter(
        lambda app: app_access.user_can_access_app(request.couch_user, app),
        apps)

    def _default_lang():
        if apps:
            # unfortunately we have to go back to the DB to find this
            return Application.get(apps[0]["_id"]).build_langs[0]
        else:
            return "en"

    # default language to user's preference, followed by
    # first app's default, followed by english
    language = request.couch_user.language or _default_lang()

    def _url_context():
        # given a url path, returns potentially the app, parent, and case, if
        # they're selected. the front end optimizes with these to avoid excess
        # server calls

        # there's an annoying dependency between this logic and backbone's
        # url routing that seems hard to solve well. this needs to be synced
        # with apps.js if anything changes

        # for apps anything with "view/app/" works

        # for cases it will be:
        # "view/:app/:module/:form/case/:case/"

        # if there are parent cases, it will be:
        # "view/:app/:module/:form/parent/:parent/case/:case/

        # could use regex here but this is actually simpler with the potential
        # absence of a trailing slash
        split = urlPath.split('/')
        app_id = split[1] if len(split) >= 2 else None

        if len(split) >= 5 and split[4] == "parent":
            parent_id = split[5]
            case_id = split[7] if len(split) >= 7 else None
        else:
            parent_id = None
            case_id = split[5] if len(split) >= 6 else None

        app = None
        if app_id:
            if app_id in [a['_id'] for a in apps]:
                app = look_up_app_json(domain, app_id)
            else:
                messages.info(
                    request,
                    _("That app is no longer valid. Try using the "
                      "navigation links to select an app."))
        if app is None and len(apps) == 1:
            app = look_up_app_json(domain, apps[0]['_id'])

        def _get_case(domain, case_id):
            case = CommCareCase.get(case_id)
            assert case.domain == domain, "case %s not in %s" % (case_id,
                                                                 domain)
            return case.get_json()

        case = _get_case(domain, case_id) if case_id else None
        if parent_id is None and case is not None:
            parent_id = case.get('indices', {}).get('parent',
                                                    {}).get('case_id', None)