Ejemplo n.º 1
0
def render_map_feature_add(request, instance, type):
    if type in instance.map_feature_types[1:]:
        app = MapFeature.get_subclass(type).__module__.split(".")[0]
        template = "%s/%s_add.html" % (app, type)
        return render_to_response(template, None, RequestContext(request))
    else:
        raise Http404("Instance does not support feature type " + type)
Ejemplo n.º 2
0
 def make_display_filter(feature_name):
     Feature = MapFeature.get_subclass(feature_name)
     plural = Feature.terminology(self)['plural']
     return {
         'label': 'Show %s' % plural.lower(),
         'model': feature_name
     }
Ejemplo n.º 3
0
    def add_map_feature_types(self, types):
        """
        add_map_feature_types(self, types)

        types is a list of map feature class names.

        Add these types to the instance config,
        save the instance!!!,
        and create udf rows for udfs that have settings defaults,
        if they don't already exist.
        """
        from treemap.models import MapFeature  # prevent circular import
        from treemap.audit import add_default_permissions

        classes = [MapFeature.get_subclass(type) for type in types]

        dups = set(types) & set(self.map_feature_types)
        if len(dups) > 0:
            raise ValidationError('Map feature types already added: %s' % dups)

        self._map_feature_types = list(self.map_feature_types) + list(types)
        self.save()

        for type, clz in zip(types, classes):
            settings = (getattr(clz, 'udf_settings', {}))
            for udfc_name, udfc_settings in settings.items():
                if udfc_settings.get('defaults'):
                    get_or_create_udf(self, type, udfc_name)

        add_default_permissions(self, models=classes)
Ejemplo n.º 4
0
 def make_display_filter(feature_name):
     Feature = MapFeature.get_subclass(feature_name)
     if hasattr(Feature, 'display_name_plural'):
         plural = Feature.display_name_plural
     else:
         plural = Feature.display_name + 's'
     return {'label': 'Show %s' % plural.lower(), 'model': feature_name}
Ejemplo n.º 5
0
    def add_map_feature_types(self, types):
        """
        add_map_feature_types(self, types)

        types is a list of map feature class names.

        Add these types to the instance config,
        save the instance!!!,
        and create udf rows for udfs that have settings defaults,
        if they don't already exist.
        """
        from treemap.models import MapFeature  # prevent circular import
        from treemap.audit import add_default_permissions

        classes = [MapFeature.get_subclass(type) for type in types]

        dups = set(types) & set(self.map_feature_types)
        if len(dups) > 0:
            raise ValidationError('Map feature types already added: %s' % dups)

        self._map_feature_types = list(self.map_feature_types) + list(types)
        self.save()

        for type, clz in zip(types, classes):
            settings = (getattr(clz, 'udf_settings', {}))
            for udfc_name, udfc_settings in settings.items():
                if udfc_settings.get('defaults'):
                    get_or_create_udf(self, type, udfc_name)

        add_default_permissions(self, models=classes)
Ejemplo n.º 6
0
 def make_display_filter(feature_name):
     Feature = MapFeature.get_subclass(feature_name)
     if hasattr(Feature, "display_name_plural"):
         plural = Feature.display_name_plural
     else:
         plural = Feature.display_name + "s"
     return {"label": "Show %s" % plural.lower(), "model": feature_name}
Ejemplo n.º 7
0
def get_map_view_context(request, instance):
    resource_classes = [
        MapFeature.get_subclass(type) for type in instance.map_feature_types
    ]
    return {
        'fields_for_add_tree': [(trans('Tree Height'), 'Tree.height')],
        'resource_classes': resource_classes[1:]
    }
Ejemplo n.º 8
0
def get_map_view_context(request, instance):
    resource_classes = [MapFeature.get_subclass(type)
                        for type in instance.map_feature_types]
    return {
        'fields_for_add_tree': [
            (trans('Tree Height'), 'Tree.height')
        ],
        'resource_classes': resource_classes[1:]
    }
Ejemplo n.º 9
0
def render_map_feature_add(request, instance, type):
    if type in instance.map_feature_types[1:]:
        app = MapFeature.get_subclass(type).__module__.split('.')[0]
        try:
            template = '%s/%s_add.html' % (app, type)
        except:
            template = 'treemap/resource_add.html'
        return render(request, template, {'object_name': to_object_name(type)})
    else:
        raise_non_instance_404(type)
Ejemplo n.º 10
0
def any_resource_is_creatable(role_related_obj):
    role = _get_role_from_related_object(role_related_obj)
    if role is None:
        return False

    map_features = {MapFeature.get_subclass(m)
                    for m in role.instance.map_feature_types}
    resources = map_features - {Plot}

    return any(map_feature_is_creatable(role, Model) for Model in resources)
Ejemplo n.º 11
0
def render_map_feature_add(request, instance, type):
    if type in instance.map_feature_types[1:]:
        app = MapFeature.get_subclass(type).__module__.split('.')[0]
        try:
            template = '%s/%s_add.html' % (app, type)
        except:
            template = 'treemap/resource_add.html'
        return render(request, template, {'object_name': to_object_name(type)})
    else:
        raise_non_instance_404(type)
Ejemplo n.º 12
0
 def make_display_filter(feature_name):
     Feature = MapFeature.get_subclass(feature_name)
     if hasattr(Feature, 'display_name_plural'):
         plural = Feature.display_name_plural
     else:
         plural = Feature.display_name + 's'
     return {
         'label': 'Show %s' % plural.lower(),
         'model': feature_name
     }
Ejemplo n.º 13
0
Archivo: views.py Proyecto: heath/OTM2
def _get_map_view_context(request, instance):
    resource_types = [{'name': type,
                       'display': MapFeature.get_subclass(type).display_name}
                      for type in instance.map_feature_types]
    return {
        'fields_for_add_tree': [
            (trans('Tree Height'), 'Tree.height')
        ],
        'resource_types': resource_types[1:]
    }
Ejemplo n.º 14
0
def render_map_feature_add(request, instance, type):
    if type in instance.map_feature_types[1:]:
        app = MapFeature.get_subclass(type).__module__.split(".")[0]
        try:
            template = "%s/%s_add.html" % (app, type)
            get_template(template)
        except:
            template = "treemap/resource_add.html"
        return render_to_response(template, {"object_name": to_object_name(type)}, RequestContext(request))
    else:
        raise_non_instance_404(type)
Ejemplo n.º 15
0
def get_map_view_context(request, instance):
    resource_classes = [MapFeature.get_subclass(type)
                        for type in instance.map_feature_types]
    context = {
        'fields_for_add_tree': [
            (_('Tree Height'), 'Tree.height')
        ],
        'resource_classes': resource_classes[1:],
    }
    add_map_info_to_context(context, instance)
    return context
Ejemplo n.º 16
0
def get_map_feature_or_404(feature_id, instance, type=None):
    if type:
        MapFeatureSubclass = MapFeature.get_subclass(type)
        InstanceMapFeature = instance.scope_model(MapFeatureSubclass)
        return get_object_or_404(InstanceMapFeature, pk=feature_id)

    else:
        InstanceMapFeature = instance.scope_model(MapFeature)
        feature = get_object_or_404(InstanceMapFeature, pk=feature_id)

        # Return the concrete subtype (e.g. Plot), not a general MapFeature
        return feature.cast_to_subtype()
Ejemplo n.º 17
0
def any_resource_is_creatable(role_related_obj):
    role = _get_role_from_related_object(role_related_obj)
    if role is None:
        return False

    map_features = {
        MapFeature.get_subclass(m)
        for m in role.instance.map_feature_types
    }
    resources = map_features - {Plot}

    return any(map_feature_is_creatable(role, Model) for Model in resources)
Ejemplo n.º 18
0
def get_map_feature_or_404(feature_id, instance, type=None):
    if type:
        MapFeatureSubclass = MapFeature.get_subclass(type)
        InstanceMapFeature = instance.scope_model(MapFeatureSubclass)
        return get_object_or_404(InstanceMapFeature, pk=feature_id)

    else:
        InstanceMapFeature = instance.scope_model(MapFeature)
        feature = get_object_or_404(InstanceMapFeature, pk=feature_id)

        # Return the concrete subtype (e.g. Plot), not a general MapFeature
        return feature.cast_to_subtype()
Ejemplo n.º 19
0
def get_map_feature_or_404(feature_id, instance, type=None):
    if type:
        MapFeatureSubclass = MapFeature.get_subclass(type)
        InstanceMapFeature = instance.scope_model(MapFeatureSubclass)
        return get_object_or_404(InstanceMapFeature, pk=feature_id)

    else:
        InstanceMapFeature = instance.scope_model(MapFeature)
        feature = get_object_or_404(InstanceMapFeature, pk=feature_id)

        # Use feature_type to get the appropriate object, e.g. feature.plot
        feature = getattr(feature, feature.feature_type.lower())
        return feature
Ejemplo n.º 20
0
def get_map_feature_or_404(feature_id, instance, type=None):
    if type:
        MapFeatureSubclass = MapFeature.get_subclass(type)
        InstanceMapFeature = instance.scope_model(MapFeatureSubclass)
        return get_object_or_404(InstanceMapFeature, pk=feature_id)

    else:
        InstanceMapFeature = instance.scope_model(MapFeature)
        feature = get_object_or_404(InstanceMapFeature, pk=feature_id)

        # Use feature_type to get the appropriate object, e.g. feature.plot
        feature = getattr(feature, feature.feature_type.lower())
        return feature
Ejemplo n.º 21
0
def safe_get_model_class(model_string):
    """
    In a couple of cases we want to be able to convert a string
    into a valid django model class. For instance, if we have
    'Plot' we want to get the actual class for 'treemap.models.Plot'
    in a safe way.

    This function returns the class represented by the given model
    if it exists in 'treemap.models'
    """
    from treemap.models import MapFeature

    # All of our models live in 'treemap.models', so
    # we can start with that namespace
    models_module = __import__('treemap.models')

    if hasattr(models_module.models, model_string):
        return getattr(models_module.models, model_string)
    elif MapFeature.has_subclass(model_string):
        return MapFeature.get_subclass(model_string)
    else:
        raise ValidationError(trans('invalid model type: "%s"') % model_string)
Ejemplo n.º 22
0
Archivo: util.py Proyecto: atogle/OTM2
def safe_get_model_class(model_string):
    """
    In a couple of cases we want to be able to convert a string
    into a valid django model class. For instance, if we have
    'Plot' we want to get the actual class for 'treemap.models.Plot'
    in a safe way.

    This function returns the class represented by the given model
    if it exists in 'treemap.models'
    """
    from treemap.models import MapFeature

    # All of our models live in 'treemap.models', so
    # we can start with that namespace
    models_module = __import__('treemap.models')

    if hasattr(models_module.models, model_string):
        return getattr(models_module.models, model_string)
    elif MapFeature.has_subclass(model_string):
        return MapFeature.get_subclass(model_string)
    else:
        raise ValidationError(trans('invalid model type'))
Ejemplo n.º 23
0
def render_map_feature_add(request, instance, type):
    if type in instance.map_feature_types[1:]:
        app = MapFeature.get_subclass(type).__module__.split('.')[0]
        try:
            template = '%s/%s_add.html' % (app, type)
            get_template(template)
        except:
            template = 'treemap/resource_add.html'
        return render_to_response(template,
                                  {'object_name': to_object_name(type)},
                                  RequestContext(request))
    else:
        raise Http404('Instance does not support feature type ' + type)
Ejemplo n.º 24
0
def detail_link(thing):
    """
    Get a link to a detail view that can be shown for an
    object with this type

    For example, a 'treephoto' instance provides a link to
    the given tree.
    """
    name = thing.__class__.__name__
    nameLower = name.lower()
    if nameLower in MODEL_DETAILS:
        return MODEL_DETAILS[nameLower](thing)
    elif MapFeature.has_subclass(name):
        return MODEL_DETAILS['mapfeature'](thing)
    else:
        return None
Ejemplo n.º 25
0
def get_benefits_for_filter(filter):
    allowed_types = filter.instance.map_feature_types
    benefits, basis = {}, {}

    for C in MapFeature.subclass_dict().values():
        if C.__name__ not in allowed_types:
            continue

        ft_benefit_groups, ft_basis = _benefits_for_class(C, filter)

        _combine_benefit_basis(basis, ft_basis)
        _combine_grouped_benefits(benefits, ft_benefit_groups)

    _annotate_basis_with_extra_stats(basis)

    return benefits, basis
Ejemplo n.º 26
0
Archivo: util.py Proyecto: grafuls/OTM2
def detail_link(thing):
    """
    Get a link to a detail view that can be shown for an
    object with this type

    For example, a 'treephoto' instance provides a link to
    the given tree.
    """
    name = thing.__class__.__name__
    nameLower = name.lower()
    if nameLower in MODEL_DETAILS:
        return MODEL_DETAILS[nameLower](thing)
    elif MapFeature.has_subclass(name):
        return MODEL_DETAILS['mapfeature'](thing)
    else:
        return None
Ejemplo n.º 27
0
def get_benefits_for_filter(filter):
    allowed_types = filter.instance.map_feature_types
    benefits, basis = {}, {}

    for C in MapFeature.subclass_dict().values():
        if C.__name__ not in allowed_types:
            continue

        ft_benefit_groups, ft_basis = _benefits_for_class(C, filter)

        _combine_benefit_basis(basis, ft_basis)
        _combine_grouped_benefits(benefits, ft_benefit_groups)

    _annotate_basis_with_extra_stats(basis)

    return benefits, basis
Ejemplo n.º 28
0
def get_map_feature_or_404(feature_id, instance, type=None):
    if type:
        if type not in instance.map_feature_types:
            raise_non_instance_404(type)
        MapFeatureSubclass = MapFeature.get_subclass(type)
        InstanceMapFeature = instance.scope_model(MapFeatureSubclass)
        return get_object_or_404(InstanceMapFeature, pk=feature_id)

    else:
        InstanceMapFeature = instance.scope_model(MapFeature)
        feature = get_object_or_404(InstanceMapFeature, pk=feature_id)

        # Return the concrete subtype (e.g. Plot), not a general MapFeature
        typed_feature = feature.cast_to_subtype()
        class_name = typed_feature.__class__.__name__
        if class_name not in instance.map_feature_types:
            raise_non_instance_404(class_name)
        return typed_feature
Ejemplo n.º 29
0
def get_map_feature_or_404(feature_id, instance, type=None):
    if type:
        if type not in instance.map_feature_types:
            raise_non_instance_404(type)
        MapFeatureSubclass = MapFeature.get_subclass(type)
        InstanceMapFeature = instance.scope_model(MapFeatureSubclass)
        return get_object_or_404(InstanceMapFeature, pk=feature_id)

    else:
        InstanceMapFeature = instance.scope_model(MapFeature)
        feature = get_object_or_404(InstanceMapFeature, pk=feature_id)

        # Return the concrete subtype (e.g. Plot), not a general MapFeature
        typed_feature = feature.cast_to_subtype()
        class_name = typed_feature.__class__.__name__
        if class_name not in instance.map_feature_types:
            raise_non_instance_404(class_name)
        return typed_feature
Ejemplo n.º 30
0
    def add_map_feature_types(self, types):
        from treemap.models import MapFeature  # prevent circular import
        from treemap.audit import add_default_permissions

        classes = [MapFeature.get_subclass(type) for type in types]

        dups = set(types) & set(self.map_feature_types)
        if len(dups) > 0:
            raise ValidationError('Map feature types already added: %s' % dups)

        self.map_feature_types = list(self.map_feature_types) + list(types)
        self.save()

        for type, clz in zip(types, classes):
            settings = (getattr(clz, 'udf_settings', {}))
            for udfc_name, udfc_settings in settings.items():
                if udfc_settings.get('defaults'):
                    get_or_create_udf(self, type, udfc_name)

        add_default_permissions(self, models=classes)
Ejemplo n.º 31
0
    def add_map_feature_types(self, types):
        from treemap.models import MapFeature  # prevent circular import
        from treemap.audit import add_default_permissions

        classes = [MapFeature.get_subclass(type) for type in types]

        dups = set(types) & set(self.map_feature_types)
        if len(dups) > 0:
            raise ValidationError('Map feature types already added: %s' % dups)

        self.map_feature_types = list(self.map_feature_types) + list(types)
        self.save()

        for type, clz in zip(types, classes):
            settings = (getattr(clz, 'udf_settings', {}))
            for udfc_name, udfc_settings in settings.items():
                if udfc_settings.get('defaults'):
                    get_or_create_udf(self, type, udfc_name)

        add_default_permissions(self, models=classes)
Ejemplo n.º 32
0
Archivo: util.py Proyecto: grafuls/OTM2
def audit_detail_link(audit):
    """
    Get a link to a detail view that can be shown for this audit

    For example, an audit on 'treephoto' provides a link to
    the given tree.
    """
    model = audit.model

    if model in MapFeature.subclass_dict().keys():
        model = 'mapfeature'

    model = model.lower()

    if model in AUDIT_MODEL_LOOKUP_FNS:
        try:
            lkp_fn = AUDIT_MODEL_LOOKUP_FNS[model]
            obj = lkp_fn(audit.model_id)
            return detail_link(obj)
        except ObjectDoesNotExist:
            return None
    else:
        return None
Ejemplo n.º 33
0
def audit_detail_link(audit):
    """
    Get a link to a detail view that can be shown for this audit

    For example, an audit on 'treephoto' provides a link to
    the given tree.
    """
    model = audit.model

    if model in MapFeature.subclass_dict().keys():
        model = 'mapfeature'

    model = model.lower()

    if model in AUDIT_MODEL_LOOKUP_FNS:
        try:
            lkp_fn = AUDIT_MODEL_LOOKUP_FNS[model]
            obj = lkp_fn(audit.model_id)
            return detail_link(obj)
        except ObjectDoesNotExist:
            return None
    else:
        return None
Ejemplo n.º 34
0
 def get_plural_feature_name(feature_name):
     if feature_name == 'Tree':
         Feature = Tree
     else:
         Feature = MapFeature.get_subclass(feature_name)
     return Feature.terminology(instance)['plural']
Ejemplo n.º 35
0
 def get_plural_feature_name(feature_name):
     if feature_name == 'Tree':
         Feature = Tree
     else:
         Feature = MapFeature.get_subclass(feature_name)
     return Feature.terminology(instance)['plural']
Ejemplo n.º 36
0
def get_audits(logged_in_user,
               instance,
               query_vars,
               user=None,
               models=ALLOWED_MODELS,
               model_id=None,
               start_id=None,
               prev_start_ids=[],
               page_size=PAGE_DEFAULT,
               exclude_pending=True,
               should_count=False):
    if instance:
        if instance.is_accessible_by(logged_in_user):
            instances = Instance.objects.filter(pk=instance.pk)
        else:
            instances = Instance.objects.none()
    # If we didn't specify an instance we only want to
    # show audits where the user has permission
    else:
        instances = Instance.objects\
            .filter(user_accessible_instance_filter(logged_in_user))
        if user:
            instances = instances.filter(pk__in=_instance_ids_edited_by(user))
        instances = instances.distinct()

    if not instances.exists():
        # Force no results
        return {
            'audits': Audit.objects.none(),
            'total_count': 0,
            'next_page': None,
            'prev_page': None
        }

    map_feature_models = set(MapFeature.subclass_dict().keys())
    model_filter = Q()
    # We only want to show the TreePhoto's image, not other fields
    # and we want to do it automatically if 'Tree' was specified as
    # a model.  The same goes for MapFeature(s) <-> MapFeaturePhoto
    # There is no need to check permissions, because photos are always visible
    if 'Tree' in models:
        model_filter = model_filter | Q(model='TreePhoto', field='image')
    if map_feature_models.intersection(models):
        model_filter = model_filter | Q(model='MapFeaturePhoto', field='image')

    for inst in instances:
        eligible_models = ({'Tree', 'TreePhoto', 'MapFeaturePhoto'}
                           | set(inst.map_feature_types)) & set(models)

        if logged_in_user == user:
            eligible_udfs = {
                'udf:%s' % udf.id
                for udf in udf_defs(inst)
                if udf.model_type in eligible_models and udf.iscollection
            }

            # The logged-in user can see all their own edits
            model_filter = model_filter | Q(
                instance=inst, model__in=(eligible_models | eligible_udfs))

        else:
            # Filter other users' edits by their visibility to the
            # logged-in user
            for model in eligible_models:
                ModelClass = get_auditable_class(model)
                fake_model = ModelClass(instance=inst)
                if issubclass(ModelClass, Authorizable):
                    visible_fields = fake_model.visible_fields(logged_in_user)
                    model_filter = model_filter |\
                        Q(model=model, field__in=visible_fields, instance=inst)
                else:
                    model_filter = model_filter | Q(model=model, instance=inst)

                if issubclass(ModelClass, UDFModel):
                    model_collection_udfs_audit_names = (
                        fake_model.visible_collection_udfs_audit_names(
                            logged_in_user))

                    model_filter = model_filter | (Q(
                        model__in=model_collection_udfs_audit_names))

    udf_bookkeeping_fields = Q(model__startswith='udf:',
                               field__in=('id', 'model_id',
                                          'field_definition'))

    audits = (Audit.objects.filter(model_filter).filter(
        instance__in=instances).select_related('instance').exclude(
            udf_bookkeeping_fields).exclude(
                user=User.system_user()).order_by('-pk'))

    if user:
        audits = audits.filter(user=user)
    if model_id:
        audits = audits.filter(model_id=model_id)
    if exclude_pending:
        audits = audits.exclude(requires_auth=True, ref__isnull=True)

    # Slicing the QuerySet uses a SQL Limit, which has proven to be quite slow.
    # By relying on the fact the our list is ordered by primary key from newest
    # to oldest, we can rely on the index on the primary key, which is faster.
    if start_id is not None:
        audits = audits.filter(pk__lte=start_id)

    total_count = audits.count() if should_count else 0
    audits = audits[:page_size]

    # Coerce the queryset into a list so we can get the last audit row on the
    # current page
    audits = list(audits)

    # We are using len(audits) instead of audits.count() because we
    # have already realized the queryset at this point
    if len(audits) == page_size:
        query_vars.setlist('prev', prev_start_ids + [audits[0].pk])
        query_vars['start'] = audits[-1].pk - 1
        next_page = "?" + query_vars.urlencode()
    else:
        next_page = None

    if prev_start_ids:
        if len(prev_start_ids) == 1:
            del query_vars['prev']
            del query_vars['start']
        else:
            prev_start_id = prev_start_ids.pop()
            query_vars.setlist('prev', prev_start_ids)
            query_vars['start'] = prev_start_id
        prev_page = "?" + query_vars.urlencode()
    else:
        prev_page = None

    return {
        'audits': audits,
        'total_count': total_count,
        'next_page': next_page,
        'prev_page': prev_page
    }
Ejemplo n.º 37
0
def add_map_feature(request, instance, type='Plot'):
    if type not in instance.map_feature_types:
        raise_non_instance_404(type)
    feature = MapFeature.get_subclass(type)(instance=instance)
    return _request_to_update_map_feature(request, feature)
Ejemplo n.º 38
0
def add_map_feature(request, instance, type='Plot'):
    if type not in instance.map_feature_types:
        raise_non_instance_404(type)
    feature = MapFeature.get_subclass(type)(instance=instance)
    return _request_to_update_map_feature(request, feature)
Ejemplo n.º 39
0
 def make_display_filter(feature_name):
     feature = MapFeature.get_subclass(feature_name)()
     return {
         'label': 'Show %ss' % feature.display_name,
         'in_value': feature_name
     }
Ejemplo n.º 40
0
def field_perm_models(instance):
    return {Tree} | {
        MapFeature.get_subclass(m)
        for m in instance.map_feature_types
    }
Ejemplo n.º 41
0
def model_perm_models(instance):
    return {Instance, Tree, TreePhoto, MapFeaturePhoto} | {
        MapFeature.get_subclass(m) for m in instance.map_feature_types}
Ejemplo n.º 42
0
Archivo: user.py Proyecto: PyBulls/OTM2
def get_audits(logged_in_user, instance, query_vars, user, models,
               model_id, page=0, page_size=20, exclude_pending=True,
               should_count=False):
    start_pos = page * page_size
    end_pos = start_pos + page_size

    if instance:
        if instance.is_accessible_by(logged_in_user):
            instances = Instance.objects.filter(pk=instance.pk)
        else:
            instances = []
    # If we didn't specify an instance we only want to
    # show audits where the user has permission
    else:
        instances = Instance.objects.filter(
            user_accessible_instance_filter(logged_in_user))

    if len(instances) == 0:
        # Force no results
        return {'audits': [],
                'total_count': 0,
                'next_page': None,
                'prev_page': None}

    map_feature_models = set(MapFeature.subclass_dict().keys())
    model_filter = Q()
    # We only want to show the TreePhoto's image, not other fields
    # and we want to do it automatically if 'Tree' was specified as
    # a model.  The same goes for MapFeature(s) <-> MapFeaturePhoto
    # There is no need to check permissions, because photos are always visible
    if 'Tree' in models:
        model_filter = model_filter | Q(model='TreePhoto', field='image')
    if map_feature_models.intersection(models):
        model_filter = model_filter | Q(model='MapFeaturePhoto', field='image')

    if logged_in_user == user:
        # The logged-in user can see all their own edits
        model_filter = model_filter | \
            Q(model__in=models) | Q(model__startswith='udf:')
    else:
        # Filter other users' edits by their visibility to the logged-in user
        for inst in instances:
            for model in models:
                ModelClass = get_auditable_class(model)
                if issubclass(ModelClass, Authorizable):
                    fake_model = ModelClass(instance=inst)
                    visible_fields = fake_model.visible_fields(logged_in_user)
                    model_filter = model_filter |\
                        Q(model=model, field__in=visible_fields, instance=inst)
                else:
                    model_filter = model_filter | Q(model=model, instance=inst)

                # Add UDF collections related to model
                if model == 'Tree':
                    fake_model = Tree(instance=inst)
                elif model == 'Plot':
                    fake_model = Plot(instance=inst)
                else:
                    continue

                model_collection_udfs_audit_names =\
                    fake_model.visible_collection_udfs_audit_names(
                        logged_in_user)

                model_filter = model_filter |\
                    Q(model__in=model_collection_udfs_audit_names)

    udf_bookkeeping_fields = Q(
        model__startswith='udf:',
        field__in=('id', 'model_id', 'field_definition'))

    audits = Audit.objects \
        .filter(model_filter) \
        .filter(instance__in=instances) \
        .exclude(udf_bookkeeping_fields) \
        .exclude(user=User.system_user()) \
        .order_by('-created', 'id')

    if user:
        audits = audits.filter(user=user)
    if model_id:
        audits = audits.filter(model_id=model_id)
    if exclude_pending:
        audits = audits.exclude(requires_auth=True, ref__isnull=True)

    total_count = audits.count() if should_count else 0
    audits = audits[start_pos:end_pos]

    query_vars = {k: v for (k, v) in query_vars.iteritems() if k != 'page'}
    next_page = None
    prev_page = None
    if len(audits) == page_size:
        query_vars['page'] = page + 1
        next_page = "?" + urllib.urlencode(query_vars)
    if page > 0:
        query_vars['page'] = page - 1
        prev_page = "?" + urllib.urlencode(query_vars)

    return {'audits': audits,
            'total_count': total_count,
            'next_page': next_page,
            'prev_page': prev_page}
Ejemplo n.º 43
0
def add_map_feature(request, instance, type='Plot'):
    feature = MapFeature.create(type, instance)
    return _request_to_update_map_feature(request, instance, feature)
Ejemplo n.º 44
0
def model_perm_models(instance):
    return {Instance, Tree, TreePhoto, MapFeaturePhoto} | {
        MapFeature.get_subclass(m)
        for m in instance.map_feature_types
    }
Ejemplo n.º 45
0
 def map_feature_classes(self):
     from treemap.models import MapFeature
     classes = {MapFeature.get_subclass(m)
                for m in self.map_feature_types}
     return classes
Ejemplo n.º 46
0
 def map_feature_classes(self):
     from treemap.models import MapFeature
     classes = {MapFeature.get_subclass(m) for m in self.map_feature_types}
     return classes
Ejemplo n.º 47
0
def get_audits(logged_in_user, instance, query_vars, user=None,
               models=ALLOWED_MODELS, model_id=None, start_id=None,
               prev_start_ids=[], page_size=PAGE_DEFAULT, exclude_pending=True,
               should_count=False):
    if instance:
        if instance.is_accessible_by(logged_in_user):
            instances = Instance.objects.filter(pk=instance.pk)
        else:
            instances = Instance.objects.none()
    # If we didn't specify an instance we only want to
    # show audits where the user has permission
    else:
        instances = Instance.objects\
            .filter(user_accessible_instance_filter(logged_in_user))
        if user:
            instances = instances.filter(pk__in=_instance_ids_edited_by(user))
        instances = instances.distinct()

    if not instances.exists():
        # Force no results
        return {'audits': Audit.objects.none(),
                'total_count': 0,
                'next_page': None,
                'prev_page': None}

    map_feature_models = set(MapFeature.subclass_dict().keys())
    model_filter = Q()
    # We only want to show the TreePhoto's image, not other fields
    # and we want to do it automatically if 'Tree' was specified as
    # a model.  The same goes for MapFeature(s) <-> MapFeaturePhoto
    # There is no need to check permissions, because photos are always visible
    if 'Tree' in models:
        model_filter = model_filter | Q(model='TreePhoto', field='image')
    if map_feature_models.intersection(models):
        model_filter = model_filter | Q(model='MapFeaturePhoto', field='image')

    for inst in instances:
        eligible_models = ({'Tree', 'TreePhoto', 'MapFeaturePhoto'} |
                           set(inst.map_feature_types)) & set(models)

        if logged_in_user == user:
            eligible_udfs = {'udf:%s' % udf.id for udf in udf_defs(inst)
                             if udf.model_type in eligible_models
                             and udf.iscollection}

            # The logged-in user can see all their own edits
            model_filter = model_filter | Q(
                instance=inst, model__in=(eligible_models | eligible_udfs))

        else:
            # Filter other users' edits by their visibility to the
            # logged-in user
            for model in eligible_models:
                ModelClass = get_auditable_class(model)
                fake_model = ModelClass(instance=inst)
                if issubclass(ModelClass, Authorizable):
                    visible_fields = fake_model.visible_fields(logged_in_user)
                    model_filter = model_filter |\
                        Q(model=model, field__in=visible_fields, instance=inst)
                else:
                    model_filter = model_filter | Q(model=model, instance=inst)

                if issubclass(ModelClass, UDFModel):
                    model_collection_udfs_audit_names = (
                        fake_model.visible_collection_udfs_audit_names(
                            logged_in_user))

                    model_filter = model_filter | (
                        Q(model__in=model_collection_udfs_audit_names))

    udf_bookkeeping_fields = Q(
        model__startswith='udf:',
        field__in=('id', 'model_id', 'field_definition'))

    audits = (Audit.objects
              .filter(model_filter)
              .filter(instance__in=instances)
              .select_related('instance')
              .exclude(udf_bookkeeping_fields)
              .exclude(user=User.system_user())
              .order_by('-pk'))

    if user:
        audits = audits.filter(user=user)
    if model_id:
        audits = audits.filter(model_id=model_id)
    if exclude_pending:
        audits = audits.exclude(requires_auth=True, ref__isnull=True)

    # Slicing the QuerySet uses a SQL Limit, which has proven to be quite slow.
    # By relying on the fact the our list is ordered by primary key from newest
    # to oldest, we can rely on the index on the primary key, which is faster.
    if start_id is not None:
        audits = audits.filter(pk__lte=start_id)

    total_count = audits.count() if should_count else 0
    audits = audits[:page_size]

    # Coerce the queryset into a list so we can get the last audit row on the
    # current page
    audits = list(audits)

    # We are using len(audits) instead of audits.count() because we
    # have already realized the queryset at this point
    if len(audits) == page_size:
        query_vars.setlist('prev', prev_start_ids + [audits[0].pk])
        query_vars['start'] = audits[-1].pk - 1
        next_page = "?" + query_vars.urlencode()
    else:
        next_page = None

    if prev_start_ids:
        if len(prev_start_ids) == 1:
            del query_vars['prev']
            del query_vars['start']
        else:
            prev_start_id = prev_start_ids.pop()
            query_vars.setlist('prev', prev_start_ids)
            query_vars['start'] = prev_start_id
        prev_page = "?" + query_vars.urlencode()
    else:
        prev_page = None

    return {'audits': audits,
            'total_count': total_count,
            'next_page': next_page,
            'prev_page': prev_page}
Ejemplo n.º 48
0
def add_map_feature(request, instance, type='Plot'):
    feature = MapFeature.create(type, instance)
    return _request_to_update_map_feature(request, instance, feature)
Ejemplo n.º 49
0
def field_perm_models(instance):
    return {Tree} | {MapFeature.get_subclass(m)
                     for m in instance.map_feature_types}
Ejemplo n.º 50
0
def get_audits(logged_in_user,
               instance,
               query_vars,
               user,
               models,
               model_id,
               page=0,
               page_size=20,
               exclude_pending=True,
               should_count=False):
    start_pos = page * page_size
    end_pos = start_pos + page_size

    model_filter = Q(model__in=models)

    # We only want to show the TreePhoto's image, not other fields
    # and we want to do it automatically if 'Tree' was specified as
    # a model
    # FIXME: This should also show MapFeaturePhoto if any map feature
    #        models are in the filter
    if 'Tree' in models:
        model_filter = model_filter | Q(model='TreePhoto', field='image')

    if instance:
        if instance.is_accessible_by(logged_in_user):
            instances = Instance.objects.filter(pk=instance.pk)
        else:
            instances = []
    # If we didn't specify an instance we only want to
    # show audits where the user has permission
    else:
        instances = Instance.objects.filter(
            _user_accessible_instance_filter(logged_in_user))

    if len(instances) == 0:
        # Force no results
        return {
            'audits': [],
            'total_count': 0,
            'next_page': None,
            'prev_page': None
        }

    map_feature_models = set(MapFeature.subclass_dict().keys())
    model_filter = Q()
    # We only want to show the TreePhoto's image, not other fields
    # and we want to do it automatically if 'Tree' was specified as
    # a model.  The same goes for MapFeature(s) <-> MapFeaturePhoto
    # There is no need to check permissions, because photos are always visible
    if 'Tree' in models:
        model_filter = model_filter | Q(model='TreePhoto', field='image')
    if map_feature_models.intersection(models):
        model_filter = model_filter | Q(model='MapFeaturePhoto', field='image')

    # We need a filter per-instance in to only show fields visible to the user
    for inst in instances:
        for model in models:
            ModelClass = get_auditable_class(model)
            if issubclass(ModelClass, Authorizable):
                fake_model = ModelClass(instance=inst)
                visible_fields = fake_model.visible_fields(logged_in_user)
                model_filter = model_filter |\
                    Q(model=model, field__in=visible_fields, instance=inst)
            else:
                model_filter = model_filter | Q(model=model, instance=inst)

            # Only add UDF collections if their parent models are being shown
            if model == 'Tree':
                fake_model = Tree(instance=inst)
            elif model == 'Plot':
                fake_model = Plot(instance=inst)
            else:
                continue

            model_collection_udfs_audit_names =\
                fake_model.visible_collection_udfs_audit_names(logged_in_user)

            # Don't show the fields that every collection UDF has, because they
            # are not very interesting
            model_filter = model_filter |\
                (Q(model__in=model_collection_udfs_audit_names) &
                 ~Q(field__in=('id', 'model_id', 'field_definition')))

    audits = Audit.objects.filter(model_filter)\
                          .filter(instance__in=instances)\
                          .order_by('-created', 'id')

    if user:
        audits = audits.filter(user=user)
    if model_id:
        audits = audits.filter(model_id=model_id)
    if exclude_pending:
        audits = audits.exclude(requires_auth=True, ref__isnull=True)

    total_count = audits.count() if should_count else 0
    audits = audits[start_pos:end_pos]

    query_vars = {k: v for (k, v) in query_vars.iteritems() if k != 'page'}
    next_page = None
    prev_page = None
    if len(audits) == page_size:
        query_vars['page'] = page + 1
        next_page = "?" + urllib.urlencode(query_vars)
    if page > 0:
        query_vars['page'] = page - 1
        prev_page = "?" + urllib.urlencode(query_vars)

    return {
        'audits': audits,
        'total_count': total_count,
        'next_page': next_page,
        'prev_page': prev_page
    }
Ejemplo n.º 51
0
Archivo: user.py Proyecto: gapb/OTM2
def get_audits(logged_in_user,
               instance,
               query_vars,
               user,
               models,
               model_id,
               page=0,
               page_size=20,
               exclude_pending=True,
               should_count=False):
    start_pos = page * page_size
    end_pos = start_pos + page_size

    if instance:
        if instance.is_accessible_by(logged_in_user):
            instances = Instance.objects.filter(pk=instance.pk)
        else:
            instances = Instance.objects.none()
    # If we didn't specify an instance we only want to
    # show audits where the user has permission
    else:
        instances = Instance.objects.filter(
            user_accessible_instance_filter(logged_in_user))

    if not instances.exists():
        # Force no results
        return {
            'audits': Audit.objects.none(),
            'total_count': 0,
            'next_page': None,
            'prev_page': None
        }

    map_feature_models = set(MapFeature.subclass_dict().keys())
    model_filter = Q()
    # We only want to show the TreePhoto's image, not other fields
    # and we want to do it automatically if 'Tree' was specified as
    # a model.  The same goes for MapFeature(s) <-> MapFeaturePhoto
    # There is no need to check permissions, because photos are always visible
    if 'Tree' in models:
        model_filter = model_filter | Q(model='TreePhoto', field='image')
    if map_feature_models.intersection(models):
        model_filter = model_filter | Q(model='MapFeaturePhoto', field='image')

    if logged_in_user == user:
        # The logged-in user can see all their own edits
        model_filter = model_filter | \
            Q(model__in=models) | Q(model__startswith='udf:')
    else:
        # Filter other users' edits by their visibility to the logged-in user
        for inst in instances:
            for model in models:
                ModelClass = get_auditable_class(model)
                if issubclass(ModelClass, Authorizable):
                    fake_model = ModelClass(instance=inst)
                    visible_fields = fake_model.visible_fields(logged_in_user)
                    model_filter = model_filter |\
                        Q(model=model, field__in=visible_fields, instance=inst)
                else:
                    model_filter = model_filter | Q(model=model, instance=inst)

                # Add UDF collections related to model
                if model == 'Tree':
                    fake_model = Tree(instance=inst)
                elif model == 'Plot':
                    fake_model = Plot(instance=inst)
                else:
                    continue

                model_collection_udfs_audit_names =\
                    fake_model.visible_collection_udfs_audit_names(
                        logged_in_user)

                model_filter = model_filter |\
                    Q(model__in=model_collection_udfs_audit_names)

    udf_bookkeeping_fields = Q(model__startswith='udf:',
                               field__in=('id', 'model_id',
                                          'field_definition'))

    audits = (Audit.objects.filter(model_filter).filter(
        instance__in=instances).select_related('instance').exclude(
            udf_bookkeeping_fields).exclude(user=User.system_user()).order_by(
                '-created', 'id'))

    if user:
        audits = audits.filter(user=user)
    if model_id:
        audits = audits.filter(model_id=model_id)
    if exclude_pending:
        audits = audits.exclude(requires_auth=True, ref__isnull=True)

    total_count = audits.count() if should_count else 0
    audits = audits[start_pos:end_pos]

    query_vars = {k: v for (k, v) in query_vars.iteritems() if k != 'page'}
    next_page = None
    prev_page = None
    if audits.count() == page_size:
        query_vars['page'] = page + 1
        next_page = "?" + urllib.urlencode(query_vars)
    if page > 0:
        query_vars['page'] = page - 1
        prev_page = "?" + urllib.urlencode(query_vars)

    return {
        'audits': audits,
        'total_count': total_count,
        'next_page': next_page,
        'prev_page': prev_page
    }
Ejemplo n.º 52
0
def get_audits(logged_in_user, instance, query_vars, user, models,
               model_id, page=0, page_size=20, exclude_pending=True,
               should_count=False):
    start_pos = page * page_size
    end_pos = start_pos + page_size

    if instance:
        if instance.is_accessible_by(logged_in_user):
            instances = Instance.objects.filter(pk=instance.pk)
        else:
            instances = Instance.objects.none()
    # If we didn't specify an instance we only want to
    # show audits where the user has permission
    else:
        instances = Instance.objects\
                            .filter(pk__in=_instance_ids_edited_by(user))\
                            .filter(user_accessible_instance_filter(
                                logged_in_user))\
                            .distinct()

    if not instances.exists():
        # Force no results
        return {'audits': Audit.objects.none(),
                'total_count': 0,
                'next_page': None,
                'prev_page': None}

    map_feature_models = set(MapFeature.subclass_dict().keys())
    model_filter = Q()
    # We only want to show the TreePhoto's image, not other fields
    # and we want to do it automatically if 'Tree' was specified as
    # a model.  The same goes for MapFeature(s) <-> MapFeaturePhoto
    # There is no need to check permissions, because photos are always visible
    if 'Tree' in models:
        model_filter = model_filter | Q(model='TreePhoto', field='image')
    if map_feature_models.intersection(models):
        model_filter = model_filter | Q(model='MapFeaturePhoto', field='image')

    for inst in instances:
        eligible_models = ({'Tree', 'TreePhoto', 'MapFeaturePhoto'} |
                           set(inst.map_feature_types)) & set(models)

        if logged_in_user == user:
            eligible_udfs = {'udf:%s' % udf.id for udf in udf_defs(inst)
                             if udf.model_type in eligible_models
                             and udf.iscollection}

            # The logged-in user can see all their own edits
            model_filter = model_filter | Q(
                instance=inst, model__in=(eligible_models | eligible_udfs))

        else:
            # Filter other users' edits by their visibility to the
            # logged-in user
            for model in eligible_models:
                ModelClass = get_auditable_class(model)
                fake_model = ModelClass(instance=inst)
                if issubclass(ModelClass, Authorizable):
                    visible_fields = fake_model.visible_fields(logged_in_user)
                    model_filter = model_filter |\
                        Q(model=model, field__in=visible_fields, instance=inst)
                else:
                    model_filter = model_filter | Q(model=model, instance=inst)

                if issubclass(ModelClass, UDFModel):
                    model_collection_udfs_audit_names = (
                        fake_model.visible_collection_udfs_audit_names(
                            logged_in_user))

                    model_filter = model_filter | (
                        Q(model__in=model_collection_udfs_audit_names))

    udf_bookkeeping_fields = Q(
        model__startswith='udf:',
        field__in=('id', 'model_id', 'field_definition'))

    audits = (Audit.objects
              .filter(model_filter)
              .filter(instance__in=instances)
              .select_related('instance')
              .exclude(udf_bookkeeping_fields)
              .exclude(user=User.system_user())
              .order_by('-created'))

    if user:
        audits = audits.filter(user=user)
    if model_id:
        audits = audits.filter(model_id=model_id)
    if exclude_pending:
        audits = audits.exclude(requires_auth=True, ref__isnull=True)

    total_count = audits.count() if should_count else 0
    audits = audits[start_pos:end_pos]

    query_vars = {k: v for (k, v) in query_vars.iteritems() if k != 'page'}
    next_page = None
    prev_page = None
    # We are using len(audits) instead of audits.count() because we
    # have already realized the queryset at this point
    if len(audits) == page_size:
        query_vars['page'] = page + 1
        next_page = "?" + urllib.urlencode(query_vars)
    if page > 0:
        query_vars['page'] = page - 1
        prev_page = "?" + urllib.urlencode(query_vars)

    return {'audits': audits,
            'total_count': total_count,
            'next_page': next_page,
            'prev_page': prev_page}