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'))
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")
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)
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'))
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)
def test_delete(self): # check empty run self.assertEqual(NotificationEntry.objects.all().count(), 0) offload_task(common_tasks.delete_old_notifications, )
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)
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, )