コード例 #1
0
ファイル: user.py プロジェクト: 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}
コード例 #2
0
ファイル: user.py プロジェクト: 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
    }
コード例 #3
0
ファイル: user.py プロジェクト: OpenTreeMap/otm-core
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}
コード例 #4
0
ファイル: user.py プロジェクト: HackMichiana/otm-core
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}
コード例 #5
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
    }
コード例 #6
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
    }