示例#1
0
 def cleanup(self):
     """
     Cleanup whenever the task runner is terminated. Clear status file and
     remove pid file.
     """
     TaskRunner.remove_status()
     TaskRunner.signal_terminated()
示例#2
0
class MediaBackendSection(BackendSection):
    """
    Backend section for editing general media content such as images and
    documents.
    """
    title = 'Media'
    sections = [
        ImageBackendSection(),
        DocumentBackendSection(),
        FolderBackendSection()
    ] + ([ProcessingMediaSection()] if TaskRunner.is_available() else [])
示例#3
0
    def create_blank_external_media(self,
                                    url,
                                    filename=None,
                                    caption=None,
                                    folder=None):
        """
        Create a new (blank) media item with the given external url and
        optionally the given parent folder.
        """
        media = Media()
        media.is_blank = True
        media.external_url = url

        # generate filename based on given url
        url_parts = urlparse.urlparse(url)
        path = url_parts.path

        # filename
        if filename:
            media.filename = filename
        else:
            media.filename = os.path.basename(path)

        # generate caption from filename
        if caption:
            media.caption = caption
        else:
            media.caption = get_caption_from_filename(media.filename)

        # folder
        if folder:
            media.folder = folder

        media.save()

        # notify task runner that there is something to do
        TaskRunner.notify()

        return media
示例#4
0
    def handle(self, *args, **options):
        """
        Run command.
        """
        # sleep for a random amount of time in case we are trying to
        # start the task runner multiple times.
        time.sleep(random.uniform(0.0, 3.0))

        # immediatly exit if another instance of the task runner is
        # already running...
        if TaskRunner.is_running():
            return

        # mark ourselves as running
        TaskRunner.signal_running()

        # setup cleanup handler that is executed whenever we terminate
        signal.signal(signal.SIGTERM, self.kill_handler)

        # whenever we have a fresh re-start, notify yourself, so that we might
        # pick up any work that is left to do for us, we might have missed
        # a previous notification...
        TaskRunner.notify()

        # continiously execute background work unless we do not have any more
        # work
        while True:
            if TaskRunner.has_work():
                # indicate that there is no more work, since we are about to run
                TaskRunner.signal_no_work()

                # execute background tasks
                runner = self.create_task_runner()
                runner.run()

            # wait for further work to appear...
            if not self.wait_for_work():
                break

        # terminate
        self.cleanup()
示例#5
0
    def wait_for_work(self):
        """
        Periodically check if there is more work. After having waited for more
        work to appear for a while, stop waiting.
        """
        start_time = time.time()
        while not TaskRunner.has_work():
            # sleep and stop waiting if we get interrupted by user
            try:
                time.sleep(self.WAIT_FOR_WORK_SLEEP_SEC)
            except KeyboardInterrupt:
                return False

            # determine total waiting time so far and stop waiting once
            # we waited long enought...
            time_ellapsed_sec = time.time() - start_time
            if time_ellapsed_sec > self.MAX_WAIT_FOR_WORK_SEC:
                return False
        return True
示例#6
0
    def download_media(self, url, folder=None):
        """
        Download a media asset with given link (or receive from previously
        downloaded asset).
        """
        url = self.get_download_link(url)

        try:
            m = Media.objects.get(external_url=url)
        except Media.DoesNotExist:
            # create empty media item
            if TaskRunner.is_available():
                m = self.cms.create_blank_external_media(url, folder=folder)
            else:
                m = self.cms.create_media_from_url(url, folder=folder)
                m.external_url = url

        if m.pk is None or m.parent_id != folder.pk:
            m.parent = folder
            m.save()

        return m
示例#7
0
    def import_from_stream(self, request, stream, encoding=DETECT_ENCODING):
        """
        Import shop data from given stream, read the data as CSV data, process
        the data through model forms and import successfully validated
        data for products, SKUs, categories and images.
        """
        # create CSV reader
        self._reader = csv.reader(utf8_stream(stream, encoding=encoding),
                                  delimiter=b',',
                                  quotechar=b'"',
                                  quoting=csv.QUOTE_ALL)
        self._request = request
        self._line = 1
        self._user = request.user
        self._errors = []
        self._row_error_occured = False
        self._num_records_processed = 0

        # get cms
        self.cms = get_cms()

        # skip lines
        lines_skipped = settings.CUBANE_SHOP_IMPORT.get('skip')
        self._skip_lines(lines_skipped)

        # read headers
        (header, header_labels) = self._get_headers()

        # read data lines as dict.
        data = self._get_lines_as_dict(header)

        # verify input data
        self.verify_data(data)

        # import categories
        self.import_categories(data)

        # import varieties and options
        varieties = self.import_varieties(header_labels)
        self.import_varity_options(data, varieties)

        # import products, variety assignments and SKUs
        groups = self.import_products(data)
        self.import_variety_assignments(groups, varieties)
        self.import_product_sku(groups, varieties)

        # download and import images, but only if we have not observed any
        # errors yet, otherwise it is likely that we will end up downloading
        # media data for no good reason, since we will revert all changes due
        # to errors anyhow...
        if self._import_images and not self.has_errors:
            self.import_images(groups)

            if TaskRunner.is_available():
                TaskRunner.notify()

        # collect row-specific errors
        for row in data:
            if self._row_has_errors(row):
                for error in row.get('_errors', []):
                    self._error_on_line(
                        row.get('_line_number'), error.get('message'),
                        self._get_row_html_excerpt(row, error.get('field'),
                                                   header_labels))

        # sort error messages by line number
        self._errors.sort(key=lambda error: error.get('line'))

        # number of records processed
        self._num_records_processed = len(data)
示例#8
0
 def terminate_task_runner(self):
     """
     Terminate task runner if running.
     """
     if TaskRunner.is_available():
         TaskRunner.terminate()
示例#9
0
 def create_task_runner(self):
     """
     Create a new instance of the task runner.
     """
     return TaskRunner()
示例#10
0
    def _create_edit(self, request, pk=None, edit=False, duplicate=False):
        if not edit and len(request.FILES.getlist('media')) > 1:
            # cancel?
            if request.POST.get('cubane_form_cancel', '0') == '1':
                return self._redirect(request, 'index')

            kwargs = {}

            # create form
            if request.method == 'POST':
                form = MultiMediaForm(request.POST, request.FILES, **kwargs)
            else:
                form = MultiMediaForm(**kwargs)

            form.configure(request)

            # validate form
            if request.method == 'POST' and form.is_valid():
                # update properties in model instance
                d = form.cleaned_data

                if 'media' in request.FILES:
                    file_list = request.FILES.getlist('media')
                    n = 0
                    Progress.start(request, len(file_list))
                    first_instance = None
                    for f in file_list:
                        instance = self.model()
                        instance.parent = d.get('parent')

                        if first_instance is None:
                            first_instance = instance

                        # auto fit
                        if settings.IMAGE_FITTING_ENABLED and settings.IMAGE_FITTING_SHAPES:
                            instance.auto_fit = d.get('auto_fit')

                        # jpeg quality
                        instance.jpeg_quality = d.get('jpeg_quality')

                        # save
                        instance.save()
                        instance.upload_save_from_stream(f, request=request)
                        n += 1

                        request.changelog.create(instance)

                        # notify task runner to do the job
                        if instance.is_blank:
                            TaskRunner.notify()

                        # report progress made
                        Progress.set_progress(request, n)

                    # commit changes
                    message = '<em>%d</em> %s created.' % (
                        n, self.model._meta.verbose_name_plural)
                    change = request.changelog.commit(message,
                                                      model=self.model)

                    Progress.stop(request)

                    # ajax operation, simply return success and message
                    # information
                    if request.is_ajax():
                        return to_json_response({
                            'success':
                            True,
                            'message':
                            message,
                            'change':
                            change,
                            'next':
                            self._get_url(request, 'index', namespace=True),
                            'instance_id':
                            first_instance.pk,
                            'instance_title':
                            unicode(first_instance),
                        })

                # dialog or screen?
                if request.GET.get('create', 'false') == 'true':
                    return {
                        'dialog_created_id': instance.pk,
                        'dialog_created_title': unicode(instance)
                    }
                else:
                    return self._redirect(request, 'index')
            elif request.is_ajax():
                return to_json_response({
                    'success': False,
                    'errors': form.errors
                })

            context = {
                'form': form,
                'permissions': {
                    'create': self.user_has_permission(request.user, 'add'),
                    'view': self.user_has_permission(request.user, 'view'),
                    'edit': self.user_has_permission(request.user, 'edit')
                },
                'verbose_name': 'Multiple Media'
            }
        else:
            if request.method == 'POST':
                Progress.start(request, 1)

            context = super(MediaView,
                            self)._create_edit(request, pk, edit, duplicate)

        if isinstance(context, dict):
            context['is_images'] = isinstance(self, ImageView)

        return context