def paginate_releases(request, domain, app_id): limit = request.GET.get('limit') only_show_released = json.loads( request.GET.get('only_show_released', 'false')) build_comment = request.GET.get('build_comment') page = int(request.GET.get('page', 1)) page = max(page, 1) try: limit = int(limit) except (TypeError, ValueError): limit = 10 timezone = get_timezone_for_user(request.couch_user, domain) app_es = (AppES().start((page - 1) * limit).size(limit).sort( 'version', desc=True).domain(domain).is_build().app_id(app_id)) if only_show_released: app_es = app_es.is_released() if build_comment: app_es = app_es.build_comment(build_comment) results = app_es.exclude_source().run() app_ids = results.doc_ids apps = get_docs(Application.get_db(), app_ids) for app in apps: app.pop('translations') saved_apps = [ SavedAppBuild.wrap( app, scrap_old_conventions=False).to_saved_build_json(timezone) for app in apps ] j2me_enabled_configs = CommCareBuildConfig.j2me_enabled_config_labels() for app in saved_apps: app['include_media'] = app['doc_type'] != 'RemoteApp' app['j2me_enabled'] = app['menu_item_label'] in j2me_enabled_configs app['target_commcare_flavor'] = ( SavedAppBuild.get(app['_id']).target_commcare_flavor if toggles.TARGET_COMMCARE_FLAVOR.enabled(domain) else 'none') if toggles.APPLICATION_ERROR_REPORT.enabled(request.couch_user.username): versions = [app['version'] for app in saved_apps] num_errors_dict = _get_error_counts(domain, app_id, versions) for app in saved_apps: app['num_errors'] = num_errors_dict.get(app['version'], 0) total_apps = results.total num_pages = int(ceil(total_apps / limit)) return json_response({ 'apps': saved_apps, 'pagination': { 'total': total_apps, 'num_pages': num_pages, 'current_page': page, } })
def paginate_releases(request, domain, app_id): limit = request.GET.get('limit') only_show_released = json.loads( request.GET.get('only_show_released', 'false')) try: limit = int(limit) except (TypeError, ValueError): limit = 10 start_build_param = request.GET.get('start_build') if start_build_param and json.loads(start_build_param): start_build = json.loads(start_build_param) assert isinstance(start_build, int) else: start_build = {} timezone = get_timezone_for_user(request.couch_user, domain) saved_apps = [] batch = [None] while len(saved_apps) < limit and len(batch): batch = Application.get_db().view( 'app_manager/saved_app', startkey=[domain, app_id, start_build], endkey=[domain, app_id], descending=True, limit=limit, wrapper=lambda x: SavedAppBuild.wrap(x['value']). to_saved_build_json(timezone), ).all() if len(batch): start_build = batch[-1]['version'] - 1 saved_apps = saved_apps + [ app for app in batch if not only_show_released or app['is_released'] ] saved_apps = saved_apps[:limit] j2me_enabled_configs = CommCareBuildConfig.j2me_enabled_config_labels() for app in saved_apps: app['include_media'] = app['doc_type'] != 'RemoteApp' app['j2me_enabled'] = app['menu_item_label'] in j2me_enabled_configs app['target_commcare_flavor'] = ( SavedAppBuild.get(app['_id']).target_commcare_flavor if toggles.TARGET_COMMCARE_FLAVOR.enabled(domain) else 'none') if toggles.APPLICATION_ERROR_REPORT.enabled(request.couch_user.username): versions = [app['version'] for app in saved_apps] num_errors_dict = _get_error_counts(domain, app_id, versions) for app in saved_apps: app['num_errors'] = num_errors_dict.get(app['version'], 0) return json_response(saved_apps)
def save_copy(request, domain, app_id): """ Saves a copy of the app to a new doc. See ApplicationBase.save_copy """ track_built_app_on_hubspot.delay(request.couch_user) comment = request.POST.get('comment') app = get_app(domain, app_id) try: errors = app.validate_app() except ModuleIdMissingException: # For apps (mainly Exchange apps) that lost unique_id attributes on Module app.ensure_module_unique_ids(should_save=True) errors = app.validate_app() if not errors: try: user_id = request.couch_user.get_id timer = datadog_bucket_timer('commcare.app_build.new_release', tags=[], timing_buckets=(1, 10, 30, 60, 120, 240)) with timer: copy = make_app_build(app, comment, user_id) CouchUser.get(user_id).set_has_built_app() except BuildConflictException: return JsonResponse( { 'error': _("There is already a version build in progress. Please wait." ) }, status=400) finally: # To make a RemoteApp always available for building if app.is_remote_app(): app.save(increment_version=True) _track_build_for_app_preview(domain, request.couch_user, app_id, 'User created a build') else: copy = None copy = copy and SavedAppBuild.wrap(copy.to_json()).releases_list_json( get_timezone_for_user(request.couch_user, domain)) lang, langs = get_langs(request, app) return json_response({ "saved_app": copy, "error_html": render_to_string( "app_manager/partials/build_errors.html", { 'app': get_app(domain, app_id), 'build_errors': errors, 'domain': domain, 'langs': langs, }), })
def paginate_releases(request, domain, app_id): limit = request.GET.get('limit') try: limit = int(limit) except (TypeError, ValueError): limit = 10 start_build_param = request.GET.get('start_build') if start_build_param and json.loads(start_build_param): start_build = json.loads(start_build_param) assert isinstance(start_build, int) else: start_build = {} timezone = get_timezone_for_user(request.couch_user, domain) saved_apps = Application.get_db().view( 'app_manager/saved_app', startkey=[domain, app_id, start_build], endkey=[domain, app_id], descending=True, limit=limit, wrapper=lambda x: SavedAppBuild.wrap(x['value']).to_saved_build_json( timezone), ).all() j2me_enabled_configs = CommCareBuildConfig.j2me_enabled_config_labels() for app in saved_apps: app['include_media'] = app['doc_type'] != 'RemoteApp' app['j2me_enabled'] = app['menu_item_label'] in j2me_enabled_configs if toggles.APPLICATION_ERROR_REPORT.enabled(request.couch_user.username): versions = [app['version'] for app in saved_apps] num_errors_dict = _get_error_counts(domain, app_id, versions) for app in saved_apps: app['num_errors'] = num_errors_dict.get(app['version'], 0) return json_response(saved_apps)
def save_copy(request, domain, app_id): """ Saves a copy of the app to a new doc. See VersionedDoc.save_copy """ track_built_app_on_hubspot.delay(request.couch_user) comment = request.POST.get('comment') app = get_app(domain, app_id) try: errors = app.validate_app() except ModuleIdMissingException: # For apps (mainly Exchange apps) that lost unique_id attributes on Module app.ensure_module_unique_ids(should_save=True) errors = app.validate_app() if not errors: try: copy = app.make_build( comment=comment, user_id=request.couch_user.get_id, previous_version=app.get_latest_app(released_only=False)) copy.save(increment_version=False) finally: # To make a RemoteApp always available for building if app.is_remote_app(): app.save(increment_version=True) _track_build_for_app_preview(domain, request.couch_user, app_id, 'User created a build') else: copy = None copy = copy and SavedAppBuild.wrap(copy.to_json()).to_saved_build_json( get_timezone_for_user(request.couch_user, domain)) lang, langs = get_langs(request, app) if copy: # Set if build is supported for Java Phones j2me_enabled_configs = CommCareBuildConfig.j2me_enabled_config_labels() copy['j2me_enabled'] = copy['menu_item_label'] in j2me_enabled_configs template = get_app_manager_template( request.user, "app_manager/v1/partials/build_errors.html", "app_manager/v2/partials/build_errors.html", ) return json_response({ "saved_app": copy, "error_html": render_to_string( template, { 'request': request, 'app': get_app(domain, app_id), 'build_errors': errors, 'domain': domain, 'langs': langs, 'lang': lang }), })
def paginate_releases(request, domain, app_id): limit = request.GET.get('limit') try: limit = int(limit) except (TypeError, ValueError): limit = 10 start_build_param = request.GET.get('start_build') if start_build_param and json.loads(start_build_param): start_build = json.loads(start_build_param) assert isinstance(start_build, int) else: start_build = {} timezone = get_timezone_for_user(request.couch_user, domain) saved_apps = Application.get_db().view('app_manager/saved_app', startkey=[domain, app_id, start_build], endkey=[domain, app_id], descending=True, limit=limit, wrapper=lambda x: SavedAppBuild.wrap(x['value']).to_saved_build_json(timezone), ).all() for app in saved_apps: app['include_media'] = app['doc_type'] != 'RemoteApp' if toggles.APPLICATION_ERROR_REPORT.enabled(request.couch_user.username): versions = [app['version'] for app in saved_apps] num_errors_dict = _get_error_counts(domain, app_id, versions) for app in saved_apps: app['num_errors'] = num_errors_dict.get(app['version'], 0) return json_response(saved_apps)
def paginate_releases(request, domain, app_id): limit = request.GET.get("limit") try: limit = int(limit) except (TypeError, ValueError): limit = 10 start_build_param = request.GET.get("start_build") if start_build_param and json.loads(start_build_param): start_build = json.loads(start_build_param) assert isinstance(start_build, int) else: start_build = {} timezone = get_timezone_for_user(request.couch_user, domain) saved_apps = ( Application.get_db() .view( "app_manager/saved_app", startkey=[domain, app_id, start_build], endkey=[domain, app_id], descending=True, limit=limit, wrapper=lambda x: SavedAppBuild.wrap(x["value"]).to_saved_build_json(timezone), ) .all() ) for app in saved_apps: app["include_media"] = app["doc_type"] != "RemoteApp" return json_response(saved_apps)
def update_build_comment(request, domain, app_id): build_id = request.POST.get("build_id") try: build = SavedAppBuild.get(build_id) except ResourceNotFound: raise Http404() build.build_comment = request.POST.get("comment") build.save() return json_response({"status": "success"})
def update_build_comment(request, domain, app_id): build_id = request.POST.get('build_id') try: build = SavedAppBuild.get(build_id) except ResourceNotFound: raise Http404() build.build_comment = request.POST.get('comment') build.save() return json_response({'status': 'success'})
def save_copy(request, domain, app_id): """ Saves a copy of the app to a new doc. See VersionedDoc.save_copy """ track_built_app_on_hubspot_v2.delay(request.couch_user) comment = request.POST.get('comment') app = get_app(domain, app_id) try: errors = app.validate_app() except ModuleIdMissingException: # For apps (mainly Exchange apps) that lost unique_id attributes on Module app.ensure_module_unique_ids(should_save=True) errors = app.validate_app() if not errors: try: user_id = request.couch_user.get_id timer = datadog_bucket_timer('commcare.app_build.new_release', tags=[], timing_buckets=(1, 10, 30, 60, 120, 240)) with timer: copy = app.make_build( comment=comment, user_id=user_id, ) copy.save(increment_version=False) CouchUser.get(user_id).set_has_built_app() finally: # To make a RemoteApp always available for building if app.is_remote_app(): app.save(increment_version=True) _track_build_for_app_preview(domain, request.couch_user, app_id, 'User created a build') else: copy = None copy = copy and SavedAppBuild.wrap(copy.to_json()).releases_list_json( get_timezone_for_user(request.couch_user, domain) ) lang, langs = get_langs(request, app) if copy: # Set if build is supported for Java Phones j2me_enabled_configs = CommCareBuildConfig.j2me_enabled_config_labels() copy['j2me_enabled'] = copy['menu_item_label'] in j2me_enabled_configs return json_response({ "saved_app": copy, "error_html": render_to_string("app_manager/partials/build_errors.html", { 'request': request, 'app': get_app(domain, app_id), 'build_errors': errors, 'domain': domain, 'langs': langs, 'lang': lang }), })
def _get_batch(start_build=None, skip=None): start_build = {} if start_build is None else start_build return Application.get_db().view('app_manager/saved_app', startkey=[domain, app_id, start_build], endkey=[domain, app_id], descending=True, limit=limit, skip=skip, wrapper=lambda x: SavedAppBuild.wrap(x['value'], scrap_old_conventions=False).releases_list_json(timezone), ).all()
def save_copy(request, domain, app_id): """ Saves a copy of the app to a new doc. """ track_built_app_on_hubspot.delay(request.couch_user.get_id) comment = request.POST.get('comment') app = get_app(domain, app_id) try: user_id = request.couch_user.get_id with report_build_time(domain, app._id, 'new_release'): copy = make_app_build(app, comment, user_id) CouchUser.get(user_id).set_has_built_app() except AppValidationError as e: lang, langs = get_langs(request, app) return JsonResponse({ "saved_app": None, "error_html": render_to_string( "app_manager/partials/build_errors.html", { 'app': get_app(domain, app_id), 'build_errors': e.errors, 'domain': domain, 'langs': langs, 'toggles': toggles_enabled_for_request(request), }), }) except BuildConflictException: return JsonResponse( { 'error': _("There is already a version build in progress. Please wait.") }, status=400) except XFormValidationFailed: return JsonResponse({'error': _("Unable to validate forms.")}, status=400) finally: # To make a RemoteApp always available for building if app.is_remote_app(): app.save(increment_version=True) _track_build_for_app_preview(domain, request.couch_user, app_id, 'User created a build') copy_json = copy and SavedAppBuild.wrap(copy.to_json()).releases_list_json( get_timezone_for_user(request.couch_user, domain)) return JsonResponse({ "saved_app": copy_json, "error_html": "", })
def save_copy(request, domain, app_id): """ Saves a copy of the app to a new doc. See VersionedDoc.save_copy """ track_built_app_on_hubspot.delay(request.couch_user) comment = request.POST.get("comment") app = get_app(domain, app_id) try: errors = app.validate_app() except ModuleIdMissingException: # For apps (mainly Exchange apps) that lost unique_id attributes on Module app.ensure_module_unique_ids(should_save=True) errors = app.validate_app() if not errors: try: copy = app.make_build( comment=comment, user_id=request.couch_user.get_id, previous_version=app.get_latest_app(released_only=False), ) copy.save(increment_version=False) finally: # To make a RemoteApp always available for building if app.is_remote_app(): app.save(increment_version=True) else: copy = None copy = copy and SavedAppBuild.wrap(copy.to_json()).to_saved_build_json( get_timezone_for_user(request.couch_user, domain) ) lang, langs = get_langs(request, app) return json_response( { "saved_app": copy, "error_html": render_to_string( "app_manager/partials/build_errors.html", { "app": get_app(domain, app_id), "build_errors": errors, "domain": domain, "langs": langs, "lang": lang, }, ), } )
def paginate_releases(request, domain, app_id): limit = request.GET.get('limit') only_show_released = json.loads(request.GET.get('only_show_released', 'false')) query = request.GET.get('query') page = int(request.GET.get('page', 1)) page = max(page, 1) try: limit = int(limit) except (TypeError, ValueError): limit = 10 skip = (page - 1) * limit timezone = get_timezone_for_user(request.couch_user, domain) def _get_batch(start_build=None, skip=None): start_build = {} if start_build is None else start_build return Application.get_db().view('app_manager/saved_app', startkey=[domain, app_id, start_build], endkey=[domain, app_id], descending=True, limit=limit, skip=skip, wrapper=lambda x: ( SavedAppBuild.wrap(x['value'], scrap_old_conventions=False) .releases_list_json(timezone) ), ).all() if not bool(only_show_released or query): # If user is limiting builds by released status or build comment, it's much # harder to be performant with couch. So if they're not doing so, take shortcuts. total_apps = len(get_built_app_ids_for_app_id(domain, app_id)) saved_apps = _get_batch(skip=skip) else: app_es = ( AppES() .start((page - 1) * limit) .size(limit) .sort('version', desc=True) .domain(domain) .is_build() .app_id(app_id) ) if only_show_released: app_es = app_es.is_released() if query: app_es = app_es.add_query(build_comment(query), queries.SHOULD) try: app_es = app_es.add_query(version(int(query)), queries.SHOULD) except ValueError: pass results = app_es.exclude_source().run() total_apps = results.total app_ids = results.doc_ids apps = get_docs(Application.get_db(), app_ids) saved_apps = [ SavedAppBuild.wrap(app, scrap_old_conventions=False).releases_list_json(timezone) for app in apps ] if toggles.APPLICATION_ERROR_REPORT.enabled(request.couch_user.username): versions = [app['version'] for app in saved_apps] num_errors_dict = _get_error_counts(domain, app_id, versions) for app in saved_apps: app['num_errors'] = num_errors_dict.get(app['version'], 0) num_pages = int(ceil(total_apps / limit)) return json_response({ 'apps': saved_apps, 'pagination': { 'total': total_apps, 'num_pages': num_pages, 'current_page': page, 'more': page * limit < total_apps, # needed when select2 uses this endpoint } })
def paginate_releases(request, domain, app_id): limit = request.GET.get('limit') only_show_released = json.loads( request.GET.get('only_show_released', 'false')) query = request.GET.get('query') page = int(request.GET.get('page', 1)) page = max(page, 1) try: limit = int(limit) except (TypeError, ValueError): limit = 10 skip = (page - 1) * limit timezone = get_timezone_for_user(request.couch_user, domain) def _get_batch(start_build=None, skip=None): start_build = {} if start_build is None else start_build return Application.get_db().view( 'app_manager/saved_app', startkey=[domain, app_id, start_build], endkey=[domain, app_id], descending=True, limit=limit, skip=skip, wrapper=lambda x: (SavedAppBuild.wrap(x['value'], scrap_old_conventions=False). releases_list_json(timezone)), ).all() if not bool(only_show_released or query): # If user is limiting builds by released status or build comment, it's much # harder to be performant with couch. So if they're not doing so, take shortcuts. total_apps = len(get_built_app_ids_for_app_id(domain, app_id)) saved_apps = _get_batch(skip=skip) else: app_es = (AppES().start((page - 1) * limit).size(limit).sort( 'version', desc=True).domain(domain).is_build().app_id(app_id)) if only_show_released: app_es = app_es.is_released() if query: app_es = app_es.add_query(build_comment(query), queries.SHOULD) try: app_es = app_es.add_query(version(int(query)), queries.SHOULD) except ValueError: pass results = app_es.exclude_source().run() total_apps = results.total app_ids = results.doc_ids apps = get_docs(Application.get_db(), app_ids) saved_apps = [ SavedAppBuild.wrap( app, scrap_old_conventions=False).releases_list_json(timezone) for app in apps ] if toggles.APPLICATION_ERROR_REPORT.enabled(request.couch_user.username): versions = [app['version'] for app in saved_apps] num_errors_dict = _get_error_counts(domain, app_id, versions) for app in saved_apps: app['num_errors'] = num_errors_dict.get(app['version'], 0) num_pages = int(ceil(total_apps / limit)) return json_response({ 'apps': saved_apps, 'pagination': { 'total': total_apps, 'num_pages': num_pages, 'current_page': page, 'more': page * limit < total_apps, # needed when select2 uses this endpoint } })
def paginate_releases(request, domain, app_id): limit = request.GET.get('limit') only_show_released = json.loads(request.GET.get('only_show_released', 'false')) build_comment = request.GET.get('build_comment') page = int(request.GET.get('page', 1)) page = max(page, 1) try: limit = int(limit) except (TypeError, ValueError): limit = 10 skip = (page - 1) * limit timezone = get_timezone_for_user(request.couch_user, domain) def _get_batch(start_build=None, skip=None): start_build = {} if start_build is None else start_build return Application.get_db().view('app_manager/saved_app', startkey=[domain, app_id, start_build], endkey=[domain, app_id], descending=True, limit=limit, skip=skip, wrapper=lambda x: SavedAppBuild.wrap(x['value'], scrap_old_conventions=False).releases_list_json(timezone), ).all() if not bool(only_show_released or build_comment): # If user is limiting builds by released status or build comment, it's much # harder to be performant with couch. So if they're not doing so, take shortcuts. total_apps = len(get_built_app_ids_for_app_id(domain, app_id)) saved_apps = _get_batch(skip=skip) else: app_es = ( AppES() .start((page - 1) * limit) .size(limit) .sort('version', desc=True) .domain(domain) .is_build() .app_id(app_id) ) if only_show_released: app_es = app_es.is_released() if build_comment: app_es = app_es.build_comment(build_comment) results = app_es.exclude_source().run() app_ids = results.doc_ids apps = get_docs(Application.get_db(), app_ids) saved_apps = [ SavedAppBuild.wrap(app, scrap_old_conventions=False).releases_list_json(timezone) for app in apps ] total_apps = results.total j2me_enabled_configs = CommCareBuildConfig.j2me_enabled_config_labels() for app in saved_apps: app['include_media'] = app['doc_type'] != 'RemoteApp' app['j2me_enabled'] = app['menu_item_label'] in j2me_enabled_configs app['target_commcare_flavor'] = ( SavedAppBuild.get(app['_id']).target_commcare_flavor if toggles.TARGET_COMMCARE_FLAVOR.enabled(domain) else 'none' ) if toggles.APPLICATION_ERROR_REPORT.enabled(request.couch_user.username): versions = [app['version'] for app in saved_apps] num_errors_dict = _get_error_counts(domain, app_id, versions) for app in saved_apps: app['num_errors'] = num_errors_dict.get(app['version'], 0) num_pages = int(ceil(total_apps / limit)) return json_response({ 'apps': saved_apps, 'pagination': { 'total': total_apps, 'num_pages': num_pages, 'current_page': page, } })