def context_dict_for_resource(request, resource, **kwargs): context = context_dict_for_map_feature(request, resource, **kwargs) instance = request.instance # Give them 2 for adding the resource and answering its questions total_progress_items = 3 completed_progress_items = 2 context['external_link'] = None photos = resource.photos() context['photos'] = [context_dict_for_photo(request, photo) for photo in photos] has_photos = len(photos) > 0 if has_photos: completed_progress_items += 1 context['upload_photo_endpoint'] = reverse( 'add_photo_to_map_feature', kwargs={'instance_url_name': instance.url_name, 'feature_id': resource.pk}) context['progress_percent'] = int(100 * ( completed_progress_items / total_progress_items) + .5) context['progress_messages'] = [] if not has_photos: context['progress_messages'].append(_('Add a photo')) audits = _map_feature_audits(request.user, request.instance, resource) _add_audits_to_context(audits, context) _add_share_context(context, request, photos) object_name_alias = to_object_name(context['feature'].__class__.__name__) # some features that were originally written to support plot and tree # have grown to support other resource types, but they expect a context # entry for their type, not just for 'feature'. # For example: # * Plot detail expects 'plot' and 'tree' # * Foo detail would expect 'foo' context[object_name_alias] = context['feature'] if isinstance(resource, PolygonalMapFeature): context['contained_plots'] = resource.contained_plots() area = resource.calculate_area() __, display_area = get_display_value(instance, 'greenInfrastructure', 'area', area, digits=0) display_units = get_unit_abbreviation( get_units(instance, 'greenInfrastructure', 'area')) context['area'] = area context['display_area'] = display_area context['area_units'] = display_units return context
def context_dict_for_resource(request, resource, **kwargs): context = context_dict_for_map_feature(request, resource, **kwargs) instance = request.instance # Give them 2 for adding the resource and answering its questions total_progress_items = 3 completed_progress_items = 2 context['external_link'] = None photos = resource.photos() context['photos'] = [ context_dict_for_photo(request, photo) for photo in photos ] has_photos = len(photos) > 0 if has_photos: completed_progress_items += 1 context['upload_photo_endpoint'] = reverse('add_photo_to_map_feature', kwargs={ 'instance_url_name': instance.url_name, 'feature_id': resource.pk }) context['progress_percent'] = int( 100 * (completed_progress_items / total_progress_items) + .5) context['progress_messages'] = [] if not has_photos: context['progress_messages'].append(_('Add a photo')) audits = _map_feature_audits(request.user, request.instance, resource) _add_audits_to_context(audits, context) _add_share_context(context, request, photos) object_name_alias = to_object_name(context['feature'].__class__.__name__) # some features that were originally written to support plot and tree # have grown to support other resource types, but they expect a context # entry for their type, not just for 'feature'. # For example: # * Plot detail expects 'plot' and 'tree' # * Foo detail would expect 'foo' context[object_name_alias] = context['feature'] if isinstance(resource, PolygonalMapFeature): context['contained_plots'] = resource.contained_plots() __, display_area = get_display_value(instance, 'greenInfrastructure', 'area', resource.calculate_area()) display_units = get_unit_abbreviation( get_units(instance, 'greenInfrastructure', 'area')) context['area'] = '{} {}'.format(display_area, display_units) return context
def wrapper(request, instance, feature_id, *args, **kwargs): error = None try: fn(request, instance, feature_id, *args, **kwargs) except ValidationError as e: error = "; ".join(e.messages) feature = get_map_feature_or_404(feature_id, instance) photos = feature.photos() return {"photos": [context_dict_for_photo(request, photo) for photo in photos], "error": error}
def wrapper(request, instance, feature_id, *args, **kwargs): error = None try: fn(request, instance, feature_id, *args, **kwargs) except ValidationError as e: error = '; '.join(e.messages) feature = get_map_feature_or_404(feature_id, instance) photos = feature.photos() return {'photos': [context_dict_for_photo(request, photo) for photo in photos], 'feature': feature, 'error': error}
def add_tree_photo(request, instance, feature_id, tree_id=None): error = None try: _, tree = add_tree_photo_helper(request, instance, feature_id, tree_id) photos = tree.photos() except ValidationError as e: trees = Tree.objects.filter(pk=tree_id) if len(trees) == 1: photos = trees[0].photos() else: photos = [] # TODO: Better display error messages in the view error = '; '.join(e.messages) return {'photos': [context_dict_for_photo(request, photo) for photo in photos], 'error': error}
def add_tree_photo(request, instance, feature_id, tree_id=None): error = None try: __, tree = add_tree_photo_helper( request, instance, feature_id, tree_id) photos = tree.photos() except ValidationError as e: trees = Tree.objects.filter(pk=tree_id) if len(trees) == 1: photos = trees[0].photos() else: photos = [] # TODO: Better display error messages in the view error = '; '.join(e.messages) return {'photos': [context_dict_for_photo(request, photo) for photo in photos], 'error': error}
def context_dict_for_resource(request, resource, **kwargs): context = context_dict_for_map_feature(request, resource, **kwargs) instance = request.instance # Give them 2 for adding the resource and answering its questions total_progress_items = 3 completed_progress_items = 2 photos = resource.photos() context["photos"] = [context_dict_for_photo(request, photo) for photo in photos] has_photos = len(photos) > 0 if has_photos: completed_progress_items += 1 context["upload_photo_endpoint"] = reverse( "add_photo_to_map_feature", kwargs={"instance_url_name": instance.url_name, "feature_id": resource.pk} ) context["progress_percent"] = int(100 * (completed_progress_items / total_progress_items) + 0.5) context["progress_messages"] = [] if not has_photos: context["progress_messages"].append(_("Add a photo")) audits = _map_feature_audits(request.user, request.instance, resource) _add_audits_to_context(audits, context) _add_share_context(context, request, photos) object_name_alias = to_object_name(context["feature"].__class__.__name__) # some features that were originally written to support plot and tree # have grown to support other resource types, but they expect a context # entry for their type, not just for 'feature'. # For example: # * Plot detail expects 'plot' and 'tree' # * Foo detail would expect 'foo' context[object_name_alias] = context["feature"] if isinstance(resource, PolygonalMapFeature): context["contained_plots"] = resource.contained_plots() return context
def context_dict_for_resource(request, resource): context = context_dict_for_map_feature(request, resource) instance = request.instance # Give them 2 for adding the resource and answering its questions total_progress_items = 3 completed_progress_items = 2 photos = resource.photos() context['photos'] = [ context_dict_for_photo(request, photo) for photo in photos ] has_photos = len(photos) > 0 if has_photos: completed_progress_items += 1 context['upload_photo_endpoint'] = reverse('add_photo_to_map_feature', kwargs={ 'instance_url_name': instance.url_name, 'feature_id': resource.pk }) context['progress_percent'] = int( 100 * (completed_progress_items / total_progress_items) + .5) context['progress_messages'] = [] if not has_photos: context['progress_messages'].append(trans('Add a photo')) audits = _map_feature_audits(request.user, request.instance, resource) _add_audits_to_context(audits, context) _add_share_context(context, request, photos) return context
def context_dict_for_resource(request, resource, **kwargs): context = context_dict_for_map_feature(request, resource, **kwargs) instance = request.instance # Give them 2 for adding the resource and answering its questions total_progress_items = 3 completed_progress_items = 2 photos = resource.photos() context['photos'] = [context_dict_for_photo(request, photo) for photo in photos] has_photos = len(photos) > 0 if has_photos: completed_progress_items += 1 context['upload_photo_endpoint'] = reverse( 'add_photo_to_map_feature', kwargs={'instance_url_name': instance.url_name, 'feature_id': resource.pk}) context['progress_percent'] = int(100 * ( completed_progress_items / total_progress_items) + .5) context['progress_messages'] = [] if not has_photos: context['progress_messages'].append(_('Add a photo')) audits = _map_feature_audits(request.user, request.instance, resource) _add_audits_to_context(audits, context) _add_share_context(context, request, photos) return context
def add_photo(request, instance, plot_id): treephoto, __ = add_tree_photo_helper(request, instance, plot_id) return context_dict_for_photo(request, treephoto)
def map_feature_photo_detail(request, instance, feature_id, photo_id): feature = get_map_feature_or_404(feature_id, instance) photo = get_object_or_404(MapFeaturePhoto, pk=photo_id, map_feature=feature) return {'photo': context_dict_for_photo(request, photo)}
def map_feature_photo_detail(request, instance, feature_id, photo_id): feature = get_map_feature_or_404(feature_id, instance) photo = get_object_or_404(MapFeaturePhoto, pk=photo_id, map_feature=feature) return {'photo': context_dict_for_photo(request, photo)}
def context_dict_for_plot(request, plot, tree_id=None, **kwargs): context = context_dict_for_map_feature(request, plot, **kwargs) instance = request.instance user = request.user if tree_id: tree = get_object_or_404(Tree, instance=instance, plot=plot, pk=tree_id) else: tree = plot.current_tree() if tree: tree.convert_to_display_units() if tree is not None: photos = tree.photos() # can't send a regular photo qs because the API will # serialize this to JSON, which is not supported for qs context['photos'] = [context_dict_for_photo(request, photo) for photo in photos] else: photos = [] has_tree_diameter = tree is not None and tree.diameter is not None has_tree_species_with_code = tree is not None \ and tree.species is not None and tree.species.otm_code is not None has_photo = tree is not None and len(photos) > 0 total_progress_items = 4 completed_progress_items = 1 # there is always a plot if has_tree_diameter: completed_progress_items += 1 if has_tree_species_with_code: completed_progress_items += 1 if has_photo: completed_progress_items += 1 context['progress_percent'] = int(100 * ( completed_progress_items / total_progress_items)) context['progress_messages'] = [] if not tree: context['progress_messages'].append(_('Add a tree')) if not has_tree_diameter: context['progress_messages'].append(_('Add the diameter')) if not has_tree_species_with_code: context['progress_messages'].append(_('Add the species')) if not has_photo: context['progress_messages'].append(_('Add a photo')) url_kwargs = {'instance_url_name': instance.url_name, 'feature_id': plot.pk} if tree: url_name = 'add_photo_to_tree' url_kwargs = dict(url_kwargs.items() + [('tree_id', tree.pk)]) else: url_name = 'add_photo_to_plot' context['upload_photo_endpoint'] = reverse(url_name, kwargs=url_kwargs) context['plot'] = plot context['has_tree'] = tree is not None # Give an empty tree when there is none in order to show tree fields easily context['tree'] = tree or Tree(plot=plot, instance=instance) context['photo_upload_share_text'] = _photo_upload_share_text( plot, tree is not None) pmfs = PolygonalMapFeature.objects.filter(polygon__contains=plot.geom) if pmfs: context['containing_polygonalmapfeature'] = pmfs[0].cast_to_subtype() audits = _plot_audits(user, instance, plot) _add_audits_to_context(audits, context) _add_share_context(context, request, photos) return context
def add_photo(request, instance, plot_id): treephoto, _ = add_tree_photo_helper(request, instance, plot_id) return context_dict_for_photo(treephoto)
def context_dict_for_plot(request, plot, tree_id=None, **kwargs): context = context_dict_for_map_feature(request, plot, **kwargs) instance = request.instance user = request.user if tree_id: tree = get_object_or_404(Tree, instance=instance, plot=plot, pk=tree_id) else: tree = plot.current_tree() if tree: tree.convert_to_display_units() if tree is not None: photos = tree.photos() # can't send a regular photo qs because the API will # serialize this to JSON, which is not supported for qs context['photos'] = [ context_dict_for_photo(request, photo) for photo in photos ] else: photos = [] def get_external_link_url(user, feature, tree=None): if not user or not feature or not feature.is_plot: return None instance = feature.instance external_link_config = \ get_attr_from_json_field(instance, 'config.externalLink') or None if not external_link_config or \ not external_link_config.get('url', None) or \ not external_link_config.get('text', None): return None role = Role.objects.get_role(instance, user) if not role.has_permission('view_external_link'): return None external_url = external_link_config['url'] if not tree and -1 < external_url.find(r'#{tree.id}'): return None plot = feature.cast_to_subtype() substitutes = { 'planting_site.id': str(plot.pk), 'planting_site.custom_id': plot.owner_orig_id or '', 'tree.id': tree and str(tree.pk) or '' } class UrlTemplate(Template): delimiter = '#' pattern = ''' \#(?: (?P<escaped>\#) | # escape with repeated delimiter (?P<named>(?:{0})) | # "#foo" substitutes foo keyword {{(?P<braced>(?:{0}))}} | # "#{{foo}}" substitutes foo keyword (?P<invalid>{{}}) # requires a name ) '''.format(get_external_link_choice_pattern()) return UrlTemplate(external_url).safe_substitute(substitutes) context['external_link'] = get_external_link_url(user, plot, tree) has_tree_diameter = tree is not None and tree.diameter is not None has_tree_species_with_code = tree is not None \ and tree.species is not None and tree.species.otm_code is not None has_photo = tree is not None and len(photos) > 0 total_progress_items = 4 completed_progress_items = 1 # there is always a plot if has_tree_diameter: completed_progress_items += 1 if has_tree_species_with_code: completed_progress_items += 1 if has_photo: completed_progress_items += 1 context['progress_percent'] = int( 100 * (completed_progress_items / total_progress_items)) context['progress_messages'] = [] if not tree: context['progress_messages'].append(_('Add a tree')) if not has_tree_diameter: context['progress_messages'].append(_('Add the diameter')) if not has_tree_species_with_code: context['progress_messages'].append(_('Add the species')) if not has_photo: context['progress_messages'].append(_('Add a photo')) url_kwargs = { 'instance_url_name': instance.url_name, 'feature_id': plot.pk } if tree: url_name = 'add_photo_to_tree' url_kwargs = dict(url_kwargs.items() + [('tree_id', tree.pk)]) else: url_name = 'add_photo_to_plot' context['upload_photo_endpoint'] = reverse(url_name, kwargs=url_kwargs) context['plot'] = plot context['has_tree'] = tree is not None # Give an empty tree when there is none in order to show tree fields easily context['tree'] = tree or Tree(plot=plot, instance=instance) context['photo_upload_share_text'] = _photo_upload_share_text( plot, tree is not None) pmfs = PolygonalMapFeature.objects.filter( polygon__contains=plot.geom, mapfeature_ptr__instance_id=instance.id) if pmfs: context['containing_polygonalmapfeature'] = pmfs[0].cast_to_subtype() audits = _plot_audits(user, instance, plot) _add_audits_to_context(audits, context) _add_share_context(context, request, photos) return context
def context_dict_for_plot(request, plot, tree_id=None, **kwargs): context = context_dict_for_map_feature(request, plot, **kwargs) instance = request.instance user = request.user if tree_id: tree = get_object_or_404(Tree, instance=instance, plot=plot, pk=tree_id) else: tree = plot.current_tree() if tree: tree.convert_to_display_units() if tree is not None: photos = tree.photos() # can't send a regular photo qs because the API will # serialize this to JSON, which is not supported for qs context['photos'] = [context_dict_for_photo(request, photo) for photo in photos] else: photos = [] has_tree_diameter = tree is not None and tree.diameter is not None has_tree_species_with_code = tree is not None \ and tree.species is not None and tree.species.otm_code is not None has_photo = tree is not None and len(photos) > 0 total_progress_items = 4 completed_progress_items = 1 # there is always a plot if has_tree_diameter: completed_progress_items += 1 if has_tree_species_with_code: completed_progress_items += 1 if has_photo: completed_progress_items += 1 context['progress_percent'] = int(100 * ( completed_progress_items / total_progress_items)) context['progress_messages'] = [] if not tree: context['progress_messages'].append(_('Add a tree')) if not has_tree_diameter: context['progress_messages'].append(_('Add the diameter')) if not has_tree_species_with_code: context['progress_messages'].append(_('Add the species')) if not has_photo: context['progress_messages'].append(_('Add a photo')) url_kwargs = {'instance_url_name': instance.url_name, 'feature_id': plot.pk} if tree: url_name = 'add_photo_to_tree' url_kwargs = dict(url_kwargs.items() + [('tree_id', tree.pk)]) else: url_name = 'add_photo_to_plot' context['upload_photo_endpoint'] = reverse(url_name, kwargs=url_kwargs) context['plot'] = plot context['has_tree'] = tree is not None # Give an empty tree when there is none in order to show tree fields easily context['tree'] = tree or Tree(plot=plot, instance=instance) context['photo_upload_share_text'] = _photo_upload_share_text( plot, tree is not None) pmfs = PolygonalMapFeature.objects.filter(polygon__contains=plot.geom) if pmfs: context['containing_polygonalmapfeature'] = pmfs[0].cast_to_subtype() audits = _plot_audits(user, instance, plot) _add_audits_to_context(audits, context) _add_share_context(context, request, photos) return context
def context_dict_for_plot(request, plot, tree_id=None, **kwargs): context = context_dict_for_map_feature(request, plot, **kwargs) instance = request.instance user = request.user if tree_id: tree = get_object_or_404(Tree, instance=instance, plot=plot, pk=tree_id) else: tree = plot.current_tree() if tree: tree.convert_to_display_units() if tree is not None: photos = tree.photos() # can't send a regular photo qs because the API will # serialize this to JSON, which is not supported for qs context['photos'] = [context_dict_for_photo(request, photo) for photo in photos] else: photos = [] def get_external_link_url(user, feature, tree=None): if not user or not feature or not feature.is_plot: return None instance = feature.instance external_link_config = \ get_attr_from_json_field(instance, 'config.externalLink') or None if not external_link_config or \ not external_link_config.get('url', None) or \ not external_link_config.get('text', None): return None role = Role.objects.get_role(instance, user) if not role.has_permission('view_external_link'): return None external_url = external_link_config['url'] if not tree and -1 < external_url.find(r'#{tree.id}'): return None plot = feature.cast_to_subtype() substitutes = { 'planting_site.id': str(plot.pk), 'planting_site.custom_id': plot.owner_orig_id or '', 'tree.id': tree and str(tree.pk) or '' } class UrlTemplate(Template): delimiter = '#' pattern = ''' \#(?: (?P<escaped>\#) | # escape with repeated delimiter (?P<named>(?:{0})) | # "#foo" substitutes foo keyword {{(?P<braced>(?:{0}))}} | # "#{{foo}}" substitutes foo keyword (?P<invalid>{{}}) # requires a name ) '''.format(get_external_link_choice_pattern()) return UrlTemplate(external_url).safe_substitute(substitutes) context['external_link'] = get_external_link_url(user, plot, tree) has_tree_diameter = tree is not None and tree.diameter is not None has_tree_species_with_code = tree is not None \ and tree.species is not None and tree.species.otm_code is not None has_photo = tree is not None and len(photos) > 0 total_progress_items = 4 completed_progress_items = 1 # there is always a plot if has_tree_diameter: completed_progress_items += 1 if has_tree_species_with_code: completed_progress_items += 1 if has_photo: completed_progress_items += 1 context['progress_percent'] = int(100 * ( completed_progress_items / total_progress_items)) context['progress_messages'] = [] if not tree: context['progress_messages'].append(_('Add a tree')) if not has_tree_diameter: context['progress_messages'].append(_('Add the diameter')) if not has_tree_species_with_code: context['progress_messages'].append(_('Add the species')) if not has_photo: context['progress_messages'].append(_('Add a photo')) url_kwargs = {'instance_url_name': instance.url_name, 'feature_id': plot.pk} if tree: url_name = 'add_photo_to_tree' url_kwargs = dict(url_kwargs.items() + [('tree_id', tree.pk)]) else: url_name = 'add_photo_to_plot' context['upload_photo_endpoint'] = reverse(url_name, kwargs=url_kwargs) context['plot'] = plot context['has_tree'] = tree is not None # Give an empty tree when there is none in order to show tree fields easily context['tree'] = tree or Tree(plot=plot, instance=instance) context['photo_upload_share_text'] = _photo_upload_share_text( plot, tree is not None) pmfs = PolygonalMapFeature.objects.filter( polygon__contains=plot.geom, mapfeature_ptr__instance_id=instance.id) if pmfs: context['containing_polygonalmapfeature'] = pmfs[0].cast_to_subtype() audits = _plot_audits(user, instance, plot) _add_audits_to_context(audits, context) _add_share_context(context, request, photos) return context