Beispiel #1
0
    def post(self, pid, record, **kwargs):
        """Send a signal to count record view for the record stats."""
        factory = RecordPermission(record, "read")
        if not factory.is_public() and not backoffice_permission().can():
            if not current_user.is_authenticated:
                abort(401)
            abort(403)

        data = request.get_json()
        event_name = data.get("event")
        if event_name == "record-view":
            record_viewed.send(
                current_app._get_current_object(),
                pid=pid,
                record=record,
            )
            return self.make_response(pid, record, 202)
        elif event_name == "file-download":
            if "key" not in data:
                abort(406, "File key is required")
            if "bucket_id" not in record:
                abort(406, "Record has no bucket")
            obj = ObjectVersion.get(record["bucket_id"], data["key"])
            file_downloaded.send(current_app._get_current_object(),
                                 obj=obj,
                                 record=record)
            return self.make_response(pid, record, 202)
        return StatsError(
            description="Invalid stats event request: {}".format(event_name))
Beispiel #2
0
 def get(self, pid, record, key):
     files = record.files
     obj = files[key]
     obj = obj.get_version(
         obj.obj.version_id)  # get the explicit version in record
     if obj.file.checksum is None:
         abort(404, 'File is not uploaded yet')
     rest_file_downloaded.send(obj)
     file_downloaded.send(obj,
                          record=record,
                          files=files,
                          file=obj,
                          pid=pid)
     return obj.send_file(restricted=self.call(self.restricted, record,
                                               obj, key),
                          as_attachment=self.call(
                              self.as_attachment, record, obj, key))
Beispiel #3
0
 def post(self, pid, record, **kwargs):
     """Send a signal to count record view for the record stats."""
     data = request.get_json()
     event_name = data.get("event")
     if event_name == "record-view":
         record_viewed.send(
             current_app._get_current_object(), pid=pid, record=record,
         )
         return self.make_response(pid, record, 202)
     elif event_name == "file-download":
         if "key" not in data:
             abort(406, "File key is required")
         if "bucket_id" not in record:
             abort(406, "Record has no bucket")
         obj = ObjectVersion.get(record["bucket_id"], data["key"])
         file_downloaded.send(
             current_app._get_current_object(), obj=obj, record=record
         )
         return self.make_response(pid, record, 202)
     return StatsError(
         description="Invalid stats event request: {}".format(event_name)
     )
Beispiel #4
0
def create_stats_fixtures(metadata, n_records, n_versions, n_files,
                          event_data, start_date, end_date, interval,
                          do_process_events=True, do_aggregate_events=True,
                          do_update_record_statistics=True):
    """Generate configurable statistics fixtures.

    :param dict metadata: Base metadata for the created records.
    :param int n_records: Number of records that will be created.
    :param int n_versions: Number of versions for each record.
    :param int n_files: Number of files for each record version.
    :param dict event_data: Base event metadata (e.g. user, user agent, etc).
    :param datetime start_date: Start date for the generated events.
    :param datetime end_date: End date for the generated events.
    :param timedelta interval: Interval between each group of events.
    :param bool do_process_events: ``True`` will run the ``process_events``
        task.
    :param bool do_aggregate_events: ``True`` will run the ``aggregate_events``
        task.
    :param bool do_update_record_statistics: ``True`` will run the
        ``update_record_statistics`` task.
    """
    records = _create_records(
        metadata, total=n_records, versions=n_versions, files=n_files)

    @contextmanager
    def _patch_stats_publish():
        original_publish = current_stats.publish

        event_batches = defaultdict(list)

        def _patched_publish(self, event_type, events):
            events[0].update(event_data)
            event_batches[event_type].append(events[0])
        current_stats.publish = MethodType(_patched_publish, current_stats)
        yield
        current_stats.publish = original_publish
        for event_type, events in event_batches.items():
            current_stats.publish(event_type, events)

    with _patch_stats_publish():
        for ts in _gen_date_range(start_date, end_date, interval):
            event_data['timestamp'] = ts.isoformat()
            for recid, record, file_objects in records:
                with current_app.test_request_context():
                    record_viewed.send(current_app._get_current_object(),
                                       pid=recid, record=record)
                    for obj in file_objects:
                        file_downloaded.send(
                            current_app._get_current_object(),
                            obj=obj, record=record)
    if do_process_events:
        process_events(['record-view', 'file-download'])
        current_search.flush_and_refresh(index='events-stats-*')

    if do_aggregate_events:
        aggregate_events(
            ['record-view-agg', 'record-view-all-versions-agg',
             'record-download-agg', 'record-download-all-versions-agg'])
        current_search.flush_and_refresh(index='stats-*')

    if do_update_record_statistics:
        update_record_statistics(start_date=start_date.isoformat(),
                                 end_date=end_date.isoformat())
        RecordIndexer().process_bulk_queue()
        current_search.flush_and_refresh(index='records')

    return records
Beispiel #5
0
def create_stats_fixtures(metadata, n_records, n_versions, n_files,
                          event_data, start_date, end_date, interval,
                          do_process_events=True, do_aggregate_events=True,
                          do_update_record_statistics=True):
    """Generate configurable statistics fixtures.

    :param dict metadata: Base metadata for the created records.
    :param int n_records: Number of records that will be created.
    :param int n_versions: Number of versions for each record.
    :param int n_files: Number of files for each record version.
    :param dict event_data: Base event metadata (e.g. user, user agent, etc).
    :param datetime start_date: Start date for the generated events.
    :param datetime end_date: End date for the generated events.
    :param timedelta interval: Interval between each group of events.
    :param bool do_process_events: ``True`` will run the ``process_events``
        task.
    :param bool do_aggregate_events: ``True`` will run the ``aggregate_events``
        task.
    :param bool do_update_record_statistics: ``True`` will run the
        ``update_record_statistics`` task.
    """
    records = _create_records(
        metadata, total=n_records, versions=n_versions, files=n_files)

    @contextmanager
    def _patch_stats_publish():
        original_publish = current_stats.publish

        event_batches = defaultdict(list)

        def _patched_publish(self, event_type, events):
            events[0].update(event_data)
            event_batches[event_type].append(events[0])
        current_stats.publish = MethodType(_patched_publish, current_stats)
        yield
        current_stats.publish = original_publish
        for event_type, events in event_batches.items():
            current_stats.publish(event_type, events)

    with _patch_stats_publish():
        for ts in _gen_date_range(start_date, end_date, interval):
            event_data['timestamp'] = ts.isoformat()
            for recid, record, file_objects in records:
                with current_app.test_request_context():
                    record_viewed.send(current_app._get_current_object(),
                                       pid=recid, record=record)
                    for obj in file_objects:
                        file_downloaded.send(
                            current_app._get_current_object(),
                            obj=obj, record=record)
    if do_process_events:
        process_events(['record-view', 'file-download'])
        current_search.flush_and_refresh(index='events-stats-*')

    if do_aggregate_events:
        aggregate_events(
            ['record-view-agg', 'record-view-all-versions-agg',
             'record-download-agg', 'record-download-all-versions-agg'])
        current_search.flush_and_refresh(index='stats-*')

    if do_update_record_statistics:
        update_record_statistics(start_date=start_date.isoformat(),
                                 end_date=end_date.isoformat())
        RecordIndexer().process_bulk_queue()
        current_search.flush_and_refresh(index='records')

    return records