Beispiel #1
0
def show_thumbnail(request, process_id):
    """Shows the thumnail of a particular result image.  Although its response
    is an image 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 result to show

    :type request: HttpRequest
    :type process_id: unicode

    :return:
      the HTTP response object with the thumbnail image

    :rtype: HttpResponse
    """
    result = get_object_or_404(models.Result, pk=utils.convert_id_to_int(process_id))
    permissions.assert_can_view_result_process(request.user, result)
    image_locations = result.get_image_locations()
    image_file = image_locations["image_file"]
    thumbnail_file = image_locations["thumbnail_file"]
    if is_update_necessary(thumbnail_file, [image_file]):
        mkdirs(thumbnail_file)
        subprocess.check_call(["convert", image_file + ("[0]" if result.image_type == "pdf" else ""),
                               "-resize", "{0}x{0}".format(settings.THUMBNAIL_WIDTH), thumbnail_file])
        storage_changed.send(models.Result)
    return static_file_response(thumbnail_file)
Beispiel #2
0
def show_thumbnail(request, process_id):
    """Shows the thumnail of a particular result image.  Although its response
    is an image 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 result to show

    :type request: HttpRequest
    :type process_id: unicode

    :return:
      the HTTP response object with the thumbnail image

    :rtype: HttpResponse
    """
    result = get_object_or_404(models.Result,
                               pk=utils.convert_id_to_int(process_id))
    permissions.assert_can_view_result_process(request.user, result)
    image_locations = result.get_image_locations()
    image_file = image_locations["image_file"]
    thumbnail_file = image_locations["thumbnail_file"]
    if is_update_necessary(thumbnail_file, [image_file]):
        mkdirs(thumbnail_file)
        subprocess.check_call([
            "convert",
            image_file + ("[0]" if result.image_type == "pdf" else ""),
            "-resize", "{0}x{0}".format(settings.THUMBNAIL_WIDTH),
            thumbnail_file
        ])
        storage_changed.send(models.Result)
    return static_file_response(thumbnail_file)
Beispiel #3
0
def plot(request, image_format):
    plot_filepath = os.path.join(settings.CACHE_ROOT, "kicker", "kicker." + image_format)
    try:
        timestamps = [models.KickerNumber.objects.latest().timestamp]
    except models.KickerNumber.DoesNotExist:
        timestamps = []
    if is_update_necessary(plot_filepath, timestamps=timestamps):
        eligible_players = [entry[0] for entry in get_eligible_players()]
        hundred_days_ago = datetime.datetime.now() - datetime.timedelta(days=100)
        plot_data = []
        for player in eligible_players:
            x_values, y_values = [], []
            latest_day = None
            kicker_numbers = list(models.KickerNumber.objects.filter(player=player, timestamp__gt=hundred_days_ago))
            for i, kicker_number in enumerate(kicker_numbers):
                if i == len(kicker_numbers) - 1 or \
                        kicker_numbers[i + 1].timestamp.toordinal() != kicker_number.timestamp.toordinal():
                    x_values.append(kicker_number.timestamp)
                    y_values.append(kicker_number.number)
            plot_data.append((x_values, y_values, player.kicker_user_details.nickname or player.username))
        if image_format == "png":
            figsize, position, legend_loc, legend_bbox, ncol = (8, 12), (0.1, 0.5, 0.8, 0.45), "upper center", [0.5, -0.1], 3
        else:
            figsize, position, legend_loc, legend_bbox, ncol = (10, 7), (0.1, 0.1, 0.6, 0.8), "best", [1, 1], 1
        figure = Figure(frameon=False, figsize=figsize)
        canvas = FigureCanvasAgg(figure)
        axes = figure.add_subplot(111)
        axes.set_position(position)
        for line in plot_data:
            if len(line[0]) == 1:
                line[0].append(line[0][0] - datetime.timedelta(days=1))
                line[1].append(line[1][0])
            axes.plot(line[0], line[1], label=line[2], linewidth=2)
        months_locator = matplotlib.dates.MonthLocator()
        axes.xaxis.set_major_locator(months_locator)
        months_formatter = matplotlib.dates.DateFormatter('%b')
        axes.xaxis.set_major_formatter(months_formatter)
        axes.grid(True)
        axes.legend(loc=legend_loc, bbox_to_anchor=legend_bbox, ncol=ncol, shadow=True)
        mkdirs(plot_filepath)
        canvas.print_figure(plot_filepath)
        figure.clf()
        storage_changed.send(models.KickerNumber)
    if not os.path.exists(plot_filepath):
        raise Http404("No kicker data available.")
    return static_file_response(plot_filepath, "kicker.pdf" if image_format == "pdf" else None)
Beispiel #4
0
def save_image_file(image_data, result, related_data_form):
    """Saves an uploaded image file stream to its final destination in
    ``settings.MEDIA_ROOT``.  If the given result has already an image connected
    with it, it is removed first.

    :param image_data: the file-like object which contains the uploaded data
        stream
    :param result: The result object for which the image was uploaded.  It is
        not necessary that all its fields are already there.  But it must have
        been written already to the database because the only necessary field
        is the primary key, which I need for the hash digest for generating the
        file names.
    :param related_data_form: A bound form with the image filename that was
        uploaded.  This is only needed for dumping error messages into it if
        something went wrong.

    :type image_data: ``django.core.files.uploadedfile.UploadedFile``
    :type result: `models.Result`
    :type related_data_form: `RelatedDataForm`
    """
    for i, chunk in enumerate(image_data.chunks()):
        if i == 0:
            if chunk.startswith(b"\211PNG\r\n\032\n"):
                new_image_type = "png"
            elif chunk.startswith(b"\xff\xd8\xff"):
                new_image_type = "jpeg"
            elif chunk.startswith(b"%PDF"):
                new_image_type = "pdf"
            else:
                related_data_form.add_error(
                    "image_file",
                    _("Invalid file format.  Only PDF, PNG, and JPEG are allowed."
                      ))
                return
            if result.image_type != "none" and new_image_type != result.image_type:
                os.remove(result.get_image_locations()["image_file"])
            result.image_type = new_image_type
            image_path = result.get_image_locations()["image_file"]
            mkdirs(image_path)
            destination = open(image_path, "wb+")
        destination.write(chunk)
    destination.close()
    storage_changed.send(models.Result)
    result.save()
Beispiel #5
0
def update_plot():
    path = os.path.join(settings.STATIC_ROOT, "kicker/")
    #    if os.path.exists(os.path.join(path, "kicker.pdf")) and os.path.exists(os.path.join(path, "kicker.png")):
    #        return
    eligible_players = [entry[0] for entry in get_eligible_players()]
    hundred_days_ago = datetime.datetime.now() - datetime.timedelta(days=100)
    plot_data = []
    for player in eligible_players:
        x_values, y_values = [], []
        latest_day = None
        kicker_numbers = list(
            models.KickerNumber.objects.filter(player=player,
                                               timestamp__gt=hundred_days_ago))
        for i, kicker_number in enumerate(kicker_numbers):
            if i == len(kicker_numbers) - 1 or \
                    kicker_numbers[i + 1].timestamp.toordinal() != kicker_number.timestamp.toordinal():
                x_values.append(kicker_number.timestamp)
                y_values.append(kicker_number.number)
        plot_data.append(
            (x_values, y_values, player.kicker_user_details.nickname
             or player.username))
    figure = Figure(frameon=False, figsize=(8, 12))
    canvas = FigureCanvasAgg(figure)
    axes = figure.add_subplot(111)
    axes.set_position((0.1, 0.5, 0.8, 0.45))
    plot_commands(axes, plot_data)
    axes.legend(loc="upper center",
                bbox_to_anchor=[0.5, -0.1],
                ncol=3,
                shadow=True)
    mkdirs(path)
    canvas.print_figure(os.path.join(path, "kicker.png"))
    figure.clf()
    figure = Figure(frameon=False, figsize=(10, 7))
    canvas = FigureCanvasAgg(figure)
    axes = figure.add_subplot(111)
    axes.set_position((0.1, 0.1, 0.6, 0.8))
    plot_commands(axes, plot_data)
    axes.legend(loc="best", bbox_to_anchor=[1, 1], shadow=True)
    canvas.print_figure(os.path.join(path, "kicker.pdf"))
    figure.clf()
    storage_changed.send(models.KickerNumber)
Beispiel #6
0
def save_image_file(image_data, result, related_data_form):
    """Saves an uploaded image file stream to its final destination in
    ``settings.MEDIA_ROOT``.  If the given result has already an image connected
    with it, it is removed first.

    :param image_data: the file-like object which contains the uploaded data
        stream
    :param result: The result object for which the image was uploaded.  It is
        not necessary that all its fields are already there.  But it must have
        been written already to the database because the only necessary field
        is the primary key, which I need for the hash digest for generating the
        file names.
    :param related_data_form: A bound form with the image filename that was
        uploaded.  This is only needed for dumping error messages into it if
        something went wrong.

    :type image_data: ``django.core.files.uploadedfile.UploadedFile``
    :type result: `models.Result`
    :type related_data_form: `RelatedDataForm`
    """
    for i, chunk in enumerate(image_data.chunks()):
        if i == 0:
            if chunk.startswith(b"\211PNG\r\n\032\n"):
                new_image_type = "png"
            elif chunk.startswith(b"\xff\xd8\xff"):
                new_image_type = "jpeg"
            elif chunk.startswith(b"%PDF"):
                new_image_type = "pdf"
            else:
                related_data_form.add_error("image_file", _("Invalid file format.  Only PDF, PNG, and JPEG are allowed."))
                return
            if result.image_type != "none" and new_image_type != result.image_type:
                os.remove(result.get_image_locations()["image_file"])
            result.image_type = new_image_type
            image_path = result.get_image_locations()["image_file"]
            mkdirs(image_path)
            destination = open(image_path, "wb+")
        destination.write(chunk)
    destination.close()
    storage_changed.send(models.Result)
    result.save()
Beispiel #7
0
def data_matrix_code(request):
    """Generates the Data Matrix representation of the given data.  The data
    is given in the ``data`` query string parameter.

    :param request: the current HTTP Request object

    :type request: HttpRequest

    :return:
      the HTTP response object

    :rtype: HttpResponse
    """
    raise Http404()
    # FixMe: This non-working currently because it write the dara matrix PNG
    # into STATIC_ROOT.  It is poorly coded for two reasons: First, STATIC_ROOT
    # may not exist because another system is serving static content.  And
    # Secondly, retrieving the actual PNG must also work even if the
    # corresponding HTML has not been retrieved yet.
    try:
        data = request.GET["data"]
    except KeyError:
        raise Http404('GET parameter "data" missing.')
    hash_ = hashlib.sha1()
    hash_.update(data.encode("utf-8"))
    filename = hash_.hexdigest() + ".png"
    filepath = os.path.join(settings.STATIC_ROOT, "data_matrix", filename)
    url = staticfiles_storage.url("data_matrix/" + filename)
    if not os.path.exists(filepath):
        mkdirs(filepath)
        image = PIL.Image.open(BytesIO(urllib.urlopen(
                    "http://www.bcgen.com/demo/IDAutomationStreamingDataMatrix.aspx?"
                    "MODE=3&D={data}&PFMT=6&PT=F&X=0.13&O=0&LM=0".format(data=urlquote_plus(data, safe="/"))).read()))
        image = image.crop((38, 3, 118, 83))
        image = PIL.ImageOps.expand(image, border=16, fill=256).convert("1")
        image.save(filepath)
        storage_changed.send(data_matrix_code)
    return render(request, "samples/data_matrix_code.html", {"title": _("Data Matrix code"),
                                                             "data_matrix_url": url,
                                                             "data": data})
Beispiel #8
0
    def export(self, path):
        """Create a hard link to the file.  Three directories are tried, in this order:

        1. /tmp
        2. CACHE_ROOT
        3. `root` (as given to `__init__`

        A failure means the the original file and the link are not on the same
        filesystem, which must be the case at least for (3).
        """
        path = os.path.join(self.root, path)
        filename = str(uuid.uuid4())
        result = os.path.join("/tmp", filename)
        try:
            os.link(path, result)
        except OSError:
            result = os.path.join(settings.CACHE_ROOT, filename)
            mkdirs(result)
            try:
                os.link(path, result)
            except OSError:
                result = os.path.join(self.root, filename)
                os.link(path, result)
        return result
Beispiel #9
0
    def export(self, path):
        """Create a hard link to the file.  Three directories are tried, in this order:

        1. /tmp
        2. CACHE_ROOT
        3. `root` (as given to `__init__`

        A failure means the the original file and the link are not on the same
        filesystem, which must be the case at least for (3).
        """
        path = os.path.join(self.root, path)
        filename = str(uuid.uuid4())
        result = os.path.join("/tmp", filename)
        try:
            os.link(path, result)
        except OSError:
            result = os.path.join(settings.CACHE_ROOT, filename)
            mkdirs(result)
            try:
                os.link(path, result)
            except OSError:
                result = os.path.join(self.root, filename)
                os.link(path, result)
        return result
Beispiel #10
0
 def export(self, path):
     with self.existing_large_object(path) as (large_object, cursor):
         result = os.path.join(settings.CACHE_ROOT, str(uuid.uuid4()))
         mkdirs(result)
         large_object.export(result)
         return result
Beispiel #11
0
 def open(self, path, mode):
     filepath = os.path.join(self.root, path)
     if mode == "w":
         mkdirs(filepath)
     return Filesystem.File(open(filepath, mode + "b"))
Beispiel #12
0
 def export(self, path):
     with self.existing_large_object(path) as (large_object, cursor):
         result = os.path.join(settings.CACHE_ROOT, str(uuid.uuid4()))
         mkdirs(result)
         large_object.export(result)
         return result
Beispiel #13
0
 def open(self, path, mode):
     filepath = os.path.join(self.root, path)
     if mode == "w":
         mkdirs(filepath)
     return Filesystem.File(open(filepath, mode + "b"))