Esempio n. 1
0
    def post(self, request, *args, **kwargs):
        """On a POST request we will attempt to refresh the exchange rates."""
        from InvenTree.tasks import offload_task, update_exchange_rates

        offload_task(update_exchange_rates, force_sync=True)

        return redirect(reverse_lazy('settings'))
Esempio n. 2
0
    def post(self, request, *args, **kwargs):
        """Check inputs and offload the task to the plugin."""
        # Which plugin to we wish to use?
        plugin = request.data.get('plugin', None)

        if not plugin:
            raise ParseError("'plugin' field must be supplied")

        # Check that the plugin exists, and supports the 'locate' mixin
        plugins = registry.with_mixin('locate')

        if plugin not in [p.slug for p in plugins]:
            raise ParseError(
                f"Plugin '{plugin}' is not installed, or does not support the location mixin"
            )

        # StockItem to identify
        item_pk = request.data.get('item', None)

        # StockLocation to identify
        location_pk = request.data.get('location', None)

        data = {
            "success": "Identification plugin activated",
            "plugin": plugin,
        }

        # StockItem takes priority
        if item_pk:
            try:
                StockItem.objects.get(pk=item_pk)

                offload_task(registry.call_plugin_function, plugin,
                             'locate_stock_item', item_pk)

                data['item'] = item_pk

                return Response(data)

            except (ValueError, StockItem.DoesNotExist):
                raise NotFound(f"StockItem matching PK '{item_pk}' not found")

        elif location_pk:
            try:
                StockLocation.objects.get(pk=location_pk)

                offload_task(registry.call_plugin_function, plugin,
                             'locate_stock_location', location_pk)

                data['location'] = location_pk

                return Response(data)

            except (ValueError, StockLocation.DoesNotExist):
                raise NotFound(
                    f"StockLocation matching PK '{location_pk}' not found")

        else:
            raise ParseError(
                "Must supply either 'item' or 'location' parameter")
Esempio n. 3
0
def register_event(event, *args, **kwargs):
    """Register the event with any interested plugins.

    Note: This function is processed by the background worker,
    as it performs multiple database access operations.
    """
    from common.models import InvenTreeSetting

    logger.debug(f"Registering triggered event: '{event}'")

    # Determine if there are any plugins which are interested in responding
    if settings.PLUGIN_TESTING or InvenTreeSetting.get_setting(
            'ENABLE_PLUGINS_EVENTS'):

        with transaction.atomic():

            for slug, plugin in registry.plugins.items():

                if plugin.mixin_enabled('events'):

                    config = plugin.plugin_config()

                    if config and config.active:

                        logger.debug(
                            f"Registering callback for plugin '{slug}'")

                        # Offload a separate task for each plugin
                        offload_task(process_event, slug, event, *args,
                                     **kwargs)
Esempio n. 4
0
    def post(self, request, *args, **kwargs):
        """
        On a POST request we will attempt to refresh the exchange rates
        """

        from InvenTree.tasks import offload_task

        # Define associated task from InvenTree.tasks list of methods
        taskname = 'InvenTree.tasks.update_exchange_rates'

        # Run it
        offload_task(taskname, force_sync=True)

        return redirect(reverse_lazy('settings'))
Esempio n. 5
0
def trigger_event(event, *args, **kwargs):
    """Trigger an event with optional arguments.

    This event will be stored in the database,
    and the worker will respond to it later on.
    """
    if not settings.PLUGINS_ENABLED:
        # Do nothing if plugins are not enabled
        return  # pragma: no cover

    # Make sure the database can be accessed and is not beeing tested rn
    if not canAppAccessDatabase() and not settings.PLUGIN_TESTING_EVENTS:
        logger.debug(
            f"Ignoring triggered event '{event}' - database not ready")
        return

    logger.debug(f"Event triggered: '{event}'")

    offload_task(register_event, event, *args, **kwargs)
Esempio n. 6
0
    def test_delete(self):

        # check empty run
        self.assertEqual(NotificationEntry.objects.all().count(), 0)
        offload_task(common_tasks.delete_old_notifications, )
Esempio n. 7
0
    def print(self, request, items_to_print):
        """
        Print this label template against a number of pre-validated items
        """

        # Check the request to determine if the user has selected a label printing plugin
        plugin = self.get_plugin(request)

        if len(items_to_print) == 0:
            # No valid items provided, return an error message

            raise ValidationError(
                'No valid objects provided to label template')

        outputs = []

        # In debug mode, generate single HTML output, rather than PDF
        debug_mode = common.models.InvenTreeSetting.get_setting(
            'REPORT_DEBUG_MODE')

        label_name = "label.pdf"

        label_names = []

        # Merge one or more PDF files into a single download
        for item in items_to_print:
            label = self.get_object()
            label.object_to_print = item

            label_name = label.generate_filename(request)

            label_names.append(label_name)

            if debug_mode:
                outputs.append(label.render_as_string(request))
            else:
                outputs.append(label.render(request))

        if not label_name.endswith(".pdf"):
            label_name += ".pdf"

        if plugin is not None:
            """
            Label printing is to be handled by a plugin,
            rather than being exported to PDF.

            In this case, we do the following:

            - Individually generate each label, exporting as an image file
            - Pass all the images through to the label printing plugin
            - Return a JSON response indicating that the printing has been offloaded

            """

            # Label instance
            label_instance = self.get_object()

            for output in outputs:
                """
                For each output, we generate a temporary image file,
                which will then get sent to the printer
                """

                # Generate a png image at 300dpi
                (img_data, w,
                 h) = output.get_document().write_png(resolution=300)

                # Construct a BytesIO object, which can be read by pillow
                img_bytes = BytesIO(img_data)

                image = Image.open(img_bytes)

                # Offload a background task to print the provided label
                offload_task(
                    plugin_label.print_label,
                    plugin.plugin_slug(),
                    image,
                    label_instance=label_instance,
                    user=request.user,
                )

            return JsonResponse({
                'plugin': plugin.plugin_slug(),
                'labels': label_names,
            })

        elif debug_mode:
            """
            Contatenate all rendered templates into a single HTML string,
            and return the string as a HTML response.
            """

            html = "\n".join(outputs)

            return HttpResponse(html)

        else:
            """
            Concatenate all rendered pages into a single PDF object,
            and return the resulting document!
            """

            pages = []

            if len(outputs) > 1:
                # If more than one output is generated, merge them into a single file
                for output in outputs:
                    doc = output.get_document()
                    for page in doc.pages:
                        pages.append(page)

                pdf = outputs[0].get_document().copy(pages).write_pdf()
            else:
                pdf = outputs[0].get_document().write_pdf()

            inline = common.models.InvenTreeUserSetting.get_setting(
                'LABEL_INLINE', user=request.user)

            return InvenTree.helpers.DownloadFile(
                pdf, label_name, content_type='application/pdf', inline=inline)
Esempio n. 8
0
 def test_delete(self):
     """Test that the task `delete_old_notifications` runs through without errors."""
     # check empty run
     self.assertEqual(NotificationEntry.objects.all().count(), 0)
     offload_task(common_tasks.delete_old_notifications, )