コード例 #1
0
ファイル: json_client.py プロジェクト: Midnighter/juliabase
def _get_solarsimulator_measurement_by_filepath(filepath, user):
    """Returns the ID of a solarsimulator measurement with the given filepath.
    Every solarsimulator measurement consists of single measurements which are
    associated with a data filepath each.  This function finds the measurement
    which contains a single (“cell”) measurement with the filepath.

    :param filepath: the path of the measurement file, as it is stored in the
        database
    :param user: the logged-in user

    :type filepath: unicode
    :type user: django.contrib.auth.models.User

    :return:
      the ID of the solarsimulator measurement which contains results from the
      given data file

    :rtype: int

    :raises permissions.PermissionError: if the user is not allowed to see the
        solarsimulator measurement
    :raises Http404: if the filepath was not found in the database
    """
    cells = institute.models.SolarsimulatorCellMeasurement.objects.filter(data_file=filepath)
    if cells.exists():
        measurement = cells[0].measurement
    else:
        raise Http404("No matching solarsimulator measurement found.")
    permissions.assert_can_view_physical_process(user, measurement)
    return measurement.id
コード例 #2
0
ファイル: json_client.py プロジェクト: msincan/juliabase
def _get_solarsimulator_measurement_by_filepath(filepath, user):
    """Returns the ID of a solarsimulator measurement with the given filepath.
    Every solarsimulator measurement consists of single measurements which are
    associated with a data filepath each.  This function finds the measurement
    which contains a single (“cell”) measurement with the filepath.

    :param filepath: the path of the measurement file, as it is stored in the
        database
    :param user: the logged-in user

    :type filepath: unicode
    :type user: django.contrib.auth.models.User

    :return:
      the ID of the solarsimulator measurement which contains results from the
      given data file

    :rtype: int

    :raises permissions.PermissionError: if the user is not allowed to see the
        solarsimulator measurement
    :raises Http404: if the filepath was not found in the database
    """
    cells = institute.models.SolarsimulatorCellMeasurement.objects.filter(data_file=filepath)
    if cells.exists():
        measurement = cells[0].measurement
    else:
        raise Http404("No matching solarsimulator measurement found.")
    permissions.assert_can_view_physical_process(user, measurement)
    return measurement.id
コード例 #3
0
ファイル: json_client.py プロジェクト: colima/juliabase
def get_matching_solarsimulator_measurement(request, sample_id, irradiation,
                                            cell_position, date):
    """Finds the solarsimulator measurement which is best suited for the given
    data file.  This view is to solve the problem that for non-standard-Jülich
    cell layouts, many single data files must be merged into one solarsimulator
    measurements.  When importing them one by one, one has to find the already
    existing measurement to which they must be added.  This is done by this
    view.

    It returns the ID of the measurement, or ``None`` if none was found.

    :param request: the HTTP request object
    :param sample_id: the ID of the sample which was measured
    :param irradiation: the irradiation (AM1.5, BG7 etc) which was used
    :param cell_position: the position of the cell on the layout; don't mix it
        up with the *index* of the cell, which is the number used in the
        Solarsimulator datafile in the first column
    :param date: the day (not the time) of the measurement in YYYY-MM-DD format

    :type request: HttpRequest
    :type sample_id: unicode
    :type irradiation: unicode
    :type cell_position: unicode
    :type date: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    try:
        filepath = request.GET["filepath"]
    except KeyError:
        raise JSONRequestException(3, '"filepath" missing')
    try:
        return respond_in_json(
            _get_solarsimulator_measurement_by_filepath(
                filepath, request.user))
    except Http404:
        sample = get_object_or_404(models.Sample, id=sample_id)
        start_date = django.utils.timezone.make_aware(
            datetime.datetime.strptime(date, "%Y-%m-%d"))
        end_date = start_date + datetime.timedelta(days=1)
        matching_measurements = institute.models.SolarsimulatorMeasurement.objects.filter(
            samples__id=sample_id, irradiation=irradiation, timestamp__gte=start_date, timestamp__lt=end_date). \
            exclude(cells__position=cell_position).order_by("timestamp")
        if matching_measurements.exists():
            solarsimulator_measurement = matching_measurements[0]
            permissions.assert_can_fully_view_sample(request.user, sample)
            permissions.assert_can_view_physical_process(
                request.user, solarsimulator_measurement)
            return respond_in_json(solarsimulator_measurement.id)
        else:
            return respond_in_json(None)
コード例 #4
0
ファイル: json_client.py プロジェクト: msincan/juliabase
def get_matching_solarsimulator_measurement(request, sample_id, irradiation, cell_position, date):
    """Finds the solarsimulator measurement which is best suited for the given
    data file.  This view is to solve the problem that for non-standard-Jülich
    cell layouts, many single data files must be merged into one solarsimulator
    measurements.  When importing them one by one, one has to find the already
    existing measurement to which they must be added.  This is done by this
    view.

    It returns the ID of the measurement, or ``None`` if none was found.

    :param request: the HTTP request object
    :param sample_id: the ID of the sample which was measured
    :param irradiation: the irradiation (AM1.5, BG7 etc) which was used
    :param cell_position: the position of the cell on the layout; don't mix it
        up with the *index* of the cell, which is the number used in the
        Solarsimulator datafile in the first column
    :param date: the day (not the time) of the measurement in YYYY-MM-DD format

    :type request: HttpRequest
    :type sample_id: unicode
    :type irradiation: unicode
    :type cell_position: unicode
    :type date: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    try:
        filepath = request.GET["filepath"]
    except KeyError:
        raise JSONRequestException(3, '"filepath" missing')
    try:
        return respond_in_json(_get_solarsimulator_measurement_by_filepath(filepath, request.user))
    except Http404:
        sample = get_object_or_404(models.Sample, id=sample_id)
        start_date = datetime.datetime.strptime(date, "%Y-%m-%d")
        end_date = start_date + datetime.timedelta(days=1)
        matching_measurements = institute.models.SolarsimulatorMeasurement.objects.filter(
            samples__id=sample_id, irradiation=irradiation, timestamp__gte=start_date, timestamp__lt=end_date). \
            exclude(cells__position=cell_position).order_by("timestamp")
        if matching_measurements.exists():
            solarsimulator_measurement = matching_measurements[0]
            permissions.assert_can_fully_view_sample(request.user, sample)
            permissions.assert_can_view_physical_process(request.user, solarsimulator_measurement)
            return respond_in_json(solarsimulator_measurement.id)
        else:
            return respond_in_json(None)
コード例 #5
0
ファイル: main.py プロジェクト: colima/juliabase
def show_process(request, process_id, process_name="Process"):
    """Show an existing physical process.  This is some sort of fallback view in
    case a process doesn't provide its own show view (which is mostly the
    case).

    The ``process_id`` needn't be the ``"id"`` field: If `process_name` is not
    ``None``, its ``JBMeta.identifying_field``, it given, is used instead for
    the lookup.

    :param request: the current HTTP Request object
    :param process_id: the ID or the process's identifying field value
    :param process_name: the class name of the process; if ``None``, ``Process``
        is assumed

    :type request: HttpRequest
    :type process_id: unicode
    :type process_name: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    process_class = get_all_models()[process_name]
    try:
        identifying_field = process_class.JBMeta.identifying_field
    except AttributeError:
        identifying_field = "id"
    try:
        process = get_object_or_404(process_class, **{
            identifying_field: process_id
        }).actual_instance
    except ValueError:
        raise Http404("Invalid value for {} passed: {}".format(
            identifying_field, repr(process_id)))
    if not isinstance(process, models.PhysicalProcess):
        raise Http404("No physical process with that ID was found.")
    permissions.assert_can_view_physical_process(request.user, process)
    if is_json_requested(request):
        return respond_in_json(process.get_data())
    template_context = {
        "title": six.text_type(process),
        "samples": process.samples.all(),
        "process": process
    }
    template_context.update(utils.digest_process(process, request.user))
    return render(request, "samples/show_process.html", template_context)
コード例 #6
0
ファイル: plots.py プロジェクト: colima/juliabase
def show_plot(request, process_id, plot_id, thumbnail):
    """Shows a particular plot.  Although its response is a bitmap rather than
    an HTML file, it is served by Django in order to enforce user permissions.

    :param request: the current HTTP Request object
    :param process_id: the database ID of the process to show
    :param plot_id: the plot_id of the image.  This is mostly ``u""`` because
        most measurement models have only one graphics.
    :param thumbnail: whether we serve a thumbnail instead of a real PDF plot

    :type request: HttpRequest
    :type process_id: unicode
    :type plot_id: unicode
    :type thumbnail: bool

    :return:
      the HTTP response object with the image

    :rtype: HttpResponse
    """
    process = get_object_or_404(models.Process,
                                pk=utils.convert_id_to_int(process_id))
    process = process.actual_instance
    permissions.assert_can_view_physical_process(request.user, process)
    plot_filepath = process.calculate_plot_locations(
        plot_id)["thumbnail_file" if thumbnail else "plot_file"]
    datafile_name = process.get_datafile_name(plot_id)
    if datafile_name is None:
        raise Http404("No such plot available.")
    timestamps = [] if thumbnail else [
        sample.last_modified for sample in process.samples.all()
    ]
    timestamps.append(process.last_modified)
    datafile_names = datafile_name if isinstance(datafile_name,
                                                 list) else [datafile_name]
    if not all(os.path.exists(filename) for filename in datafile_names):
        raise Http404("One of the raw datafiles was not found.")
    content = get_cached_file_content(
        plot_filepath,
        partial(generate_plot, process, plot_id, thumbnail, datafile_name),
        datafile_names, timestamps)
    return static_response(
        content,
        None if thumbnail else process.get_plotfile_basename(plot_id) + ".pdf",
        mimetypes.guess_type(plot_filepath))
コード例 #7
0
ファイル: json_client.py プロジェクト: colima/juliabase
def get_current_structuring(request, sample_id):
    """Find the structuring process which is active for the given sample at a
    given timestamp.  The “``timestamp``” is an optional parameter in the query
    string in the format ``YYYY-MM-YY HH:MM:SS``.  If given, find the latest
    structuring process before that timestamp.  Otherwise, find the lastest
    structuring of the sample.  Typically, the timestamp is the timestamp of
    the process which needs the structuring, e.g. a solarsimulator measurement.

    It returns the ID of the structuring process, or ``None`` if none was
    found.

    :param request: the HTTP request object
    :param sample_id: the ID of the sample

    :type request: HttpRequest
    :type sample_id: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    sample = get_object_or_404(models.Sample, id=sample_id)
    try:
        timestamp = django.utils.timezone.make_aware(
            datetime.datetime.strptime(
                request.GET["timestamp"].partition(".")[0],
                "%Y-%m-%d %H:%M:%S"))
    except KeyError:
        timestamp = None
    except ValueError:
        raise JSONRequestException(5, '"timestamp" has invalid format')
    try:
        structuring = layouts.get_current_structuring(sample, timestamp)
    except layouts.NoStructuringFound:
        result = None
    else:
        permissions.assert_can_fully_view_sample(request.user, sample)
        permissions.assert_can_view_physical_process(request.user, structuring)
        result = structuring.id
    return respond_in_json(result)
コード例 #8
0
ファイル: json_client.py プロジェクト: msincan/juliabase
def get_current_structuring(request, sample_id):
    """Find the structuring process which is active for the given sample at a
    given timestamp.  The “``timestamp``” is an optional parameter in the query
    string in the format ``YYYY-MM-YY HH:MM:SS``.  If given, find the latest
    structuring process before that timestamp.  Otherwise, find the lastest
    structuring of the sample.  Typically, the timestamp is the timestamp of
    the process which needs the structuring, e.g. a solarsimulator measurement.

    It returns the ID of the structuring process, or ``None`` if none was
    found.

    :param request: the HTTP request object
    :param sample_id: the ID of the sample

    :type request: HttpRequest
    :type sample_id: unicode

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    sample = get_object_or_404(models.Sample, id=sample_id)
    try:
        timestamp = datetime.datetime.strptime(request.GET["timestamp"].partition(".")[0], "%Y-%m-%d %H:%M:%S")
    except KeyError:
        timestamp = None
    except ValueError:
        raise JSONRequestException(5, '"timestamp" has invalid format')
    try:
        structuring = layouts.get_current_structuring(sample, timestamp)
    except layouts.NoStructuringFound:
        result = None
    else:
        permissions.assert_can_fully_view_sample(request.user, sample)
        permissions.assert_can_view_physical_process(request.user, structuring)
        result = structuring.id
    return respond_in_json(result)
コード例 #9
0
ファイル: plots.py プロジェクト: msincan/juliabase
def show_plot(request, process_id, plot_id, thumbnail):
    """Shows a particular plot.  Although its response is a bitmap rather than
    an HTML file, it is served by Django in order to enforce user permissions.

    :param request: the current HTTP Request object
    :param process_id: the database ID of the process to show
    :param plot_id: the plot_id of the image.  This is mostly ``u""`` because
        most measurement models have only one graphics.
    :param thumbnail: whether we serve a thumbnail instead of a real PDF plot

    :type request: HttpRequest
    :type process_id: unicode
    :type plot_id: unicode
    :type thumbnail: bool

    :return:
      the HTTP response object with the image

    :rtype: HttpResponse
    """
    process = get_object_or_404(models.Process, pk=utils.convert_id_to_int(process_id))
    process = process.actual_instance
    permissions.assert_can_view_physical_process(request.user, process)
    plot_filepath = process.calculate_plot_locations(plot_id)["thumbnail_file" if thumbnail else "plot_file"]
    datafile_name = process.get_datafile_name(plot_id)
    if datafile_name is None:
        raise Http404("No such plot available.")
    timestamps = [] if thumbnail else [sample.last_modified for sample in process.samples.all()]
    timestamps.append(process.last_modified)
    if datafile_name:
        datafile_names = datafile_name if isinstance(datafile_name, list) else [datafile_name]
        if not all(os.path.exists(filename) for filename in datafile_names):
            raise Http404("One of the raw datafiles was not found.")
        update_necessary = jb_common.utils.base.is_update_necessary(plot_filepath, datafile_names, timestamps)
    else:
        update_necessary = jb_common.utils.base.is_update_necessary(plot_filepath, timestamps=timestamps)
    if update_necessary:
        try:
            if thumbnail:
                figure = Figure(frameon=False, figsize=(4, 3))
                canvas = FigureCanvasAgg(figure)
                axes = figure.add_subplot(111)
                axes.set_position((0.17, 0.16, 0.78, 0.78))
                axes.grid(True)
                process.draw_plot(axes, plot_id, datafile_name, for_thumbnail=True)
                jb_common.utils.base.mkdirs(plot_filepath)
                canvas.print_figure(plot_filepath, dpi=settings.THUMBNAIL_WIDTH / 4)
            else:
                figure = Figure()
                canvas = FigureCanvasAgg(figure)
                axes = figure.add_subplot(111)
                axes.grid(True)
                axes.set_title(six.text_type(process))
                process.draw_plot(axes, plot_id, datafile_name, for_thumbnail=False)
                # FixMe: Activate this line with Matplotlib 1.1.0.
#                figure.tight_layout()
                jb_common.utils.base.mkdirs(plot_filepath)
                canvas.print_figure(plot_filepath, format="pdf")
            storage_changed.send(models.Process)
        except PlotError as e:
            raise Http404(six.text_type(e) or "Plot could not be generated.")
        except ValueError as e:
            raise Http404("Plot could not be generated: " + e.args[0])
    return jb_common.utils.base.static_file_response(plot_filepath,
                                                     None if thumbnail else process.get_plotfile_basename(plot_id) + ".pdf")
コード例 #10
0
def show_plot(request, process_id, plot_id, thumbnail):
    """Shows a particular plot.  Although its response is a bitmap rather than
    an HTML file, it is served by Django in order to enforce user permissions.

    :param request: the current HTTP Request object
    :param process_id: the database ID of the process to show
    :param plot_id: the plot_id of the image.  This is mostly ``u""`` because
        most measurement models have only one graphics.
    :param thumbnail: whether we serve a thumbnail instead of a real PDF plot

    :type request: HttpRequest
    :type process_id: unicode
    :type plot_id: unicode
    :type thumbnail: bool

    :return:
      the HTTP response object with the image

    :rtype: HttpResponse
    """
    process = get_object_or_404(models.Process, pk=utils.convert_id_to_int(process_id))
    process = process.actual_instance
    permissions.assert_can_view_physical_process(request.user, process)
    plot_filepath = process.calculate_plot_locations(plot_id)["thumbnail_file" if thumbnail else "plot_file"]
    datafile_name = process.get_datafile_name(plot_id)
    if datafile_name is None:
        raise Http404("No such plot available.")
    timestamps = [] if thumbnail else [sample.last_modified for sample in process.samples.all()]
    timestamps.append(process.last_modified)
    if datafile_name:
        datafile_names = datafile_name if isinstance(datafile_name, list) else [datafile_name]
        if not all(os.path.exists(filename) for filename in datafile_names):
            raise Http404("One of the raw datafiles was not found.")
        update_necessary = jb_common.utils.base.is_update_necessary(plot_filepath, datafile_names, timestamps)
    else:
        update_necessary = jb_common.utils.base.is_update_necessary(plot_filepath, timestamps=timestamps)
    if update_necessary:
        try:
            if thumbnail:
                figure = Figure(frameon=False, figsize=(4, 3))
                canvas = FigureCanvasAgg(figure)
                axes = figure.add_subplot(111)
                axes.set_position((0.17, 0.16, 0.78, 0.78))
                axes.grid(True)
                process.draw_plot(axes, plot_id, datafile_name, for_thumbnail=True)
                jb_common.utils.base.mkdirs(plot_filepath)
                canvas.print_figure(plot_filepath, dpi=settings.THUMBNAIL_WIDTH / 4)
            else:
                figure = Figure()
                canvas = FigureCanvasAgg(figure)
                axes = figure.add_subplot(111)
                axes.grid(True)
                axes.set_title(six.text_type(process))
                process.draw_plot(axes, plot_id, datafile_name, for_thumbnail=False)
                # FixMe: Activate this line with Matplotlib 1.1.0.
#                figure.tight_layout()
                jb_common.utils.base.mkdirs(plot_filepath)
                canvas.print_figure(plot_filepath, format="pdf")
            storage_changed.send(models.Process)
        except PlotError as e:
            raise Http404(six.text_type(e) or "Plot could not be generated.")
    return jb_common.utils.base.static_file_response(plot_filepath,
                                                     None if thumbnail else process.get_plotfile_basename(plot_id) + ".pdf")