コード例 #1
0
    def test_broadcast_content_if_genre_is_other_than_broadcast(self):
        content = {
            'genre': [{'name': 'Article', 'qcode': 'Article'}]
        }

        self.assertFalse(is_genre(content, BROADCAST_GENRE))
        self.assertTrue(is_genre(content, 'Article'))
コード例 #2
0
ファイル: broadcast.py プロジェクト: hlmnrmr/superdesk-core
    def on_broadcast_master_updated(self, item_event, item,
                                    takes_package_id=None, rewrite_id=None):
        """Runs when master item is updated.

        This event is called when the master story is corrected, published, re-written, new take/re-opened

        :param str item_event: Item operations
        :param dict item: item on which operation performed.
        :param str takes_package_id: takes_package_id.
        :param str rewrite_id: re-written story id.
        """
        status = ''

        if not item or is_genre(item, BROADCAST_GENRE):
            return

        if item_event == ITEM_CREATE and takes_package_id:
            if RE_OPENS.lower() in str(item.get('anpa_take_key', '')).lower():
                status = 'Story Re-opened'
            else:
                status = 'New Take Created'

        elif item_event == ITEM_CREATE and rewrite_id:
            status = 'Master Story Re-written'
        elif item_event == ITEM_PUBLISH:
            status = 'Master Story Published'
        elif item_event == ITEM_CORRECT:
            status = 'Master Story Corrected'

        broadcast_items = self.get_broadcast_items_from_master_story(item)

        if not broadcast_items:
            return

        processed_ids = set()
        for broadcast_item in broadcast_items:
            try:
                if broadcast_item.get('lock_user'):
                    continue

                updates = {
                    'broadcast': broadcast_item.get('broadcast'),
                }

                if status:
                    updates['broadcast']['status'] = status

                if not updates['broadcast']['takes_package_id'] and takes_package_id:
                    updates['broadcast']['takes_package_id'] = takes_package_id

                if not updates['broadcast']['rewrite_id'] and rewrite_id:
                    updates['broadcast']['rewrite_id'] = rewrite_id

                if not broadcast_item.get(config.ID_FIELD) in processed_ids:
                    self._update_broadcast_status(broadcast_item, updates)
                    # list of ids that are processed.
                    processed_ids.add(broadcast_item.get(config.ID_FIELD))
            except:
                logger.exception('Failed to update status for the broadcast item {}'.
                                 format(broadcast_item.get(config.ID_FIELD)))
コード例 #3
0
ファイル: archive_link.py プロジェクト: actionless/superdesk
    def create(self, docs, **kwargs):
        target_id = request.view_args['target_id']
        doc = docs[0]
        link_id = doc.get('link_id')
        desk_id = doc.get('desk')
        service = get_resource_service(ARCHIVE)
        target = service.find_one(req=None, _id=target_id)
        self._validate_link(target, target_id)
        link = {}

        if is_genre(target, BROADCAST_GENRE):
            raise SuperdeskApiError.badRequestError("Cannot add new take to the story with genre as broadcast.")

        if desk_id:
            link = {'task': {'desk': desk_id}}
            user = get_user()
            lookup = {'_id': desk_id, 'members.user': user['_id']}
            desk = get_resource_service('desks').find_one(req=None, **lookup)
            if not desk:
                raise SuperdeskApiError.forbiddenError("No privileges to create new take on requested desk.")

            link['task']['stage'] = desk['working_stage']

        if link_id:
            link = service.find_one(req=None, _id=link_id)

        linked_item = self.packageService.link_as_next_take(target, link)
        doc.update(linked_item)
        build_custom_hateoas(CUSTOM_HATEOAS, doc)
        return [linked_item['_id']]
コード例 #4
0
ファイル: common.py プロジェクト: akintolga/superdesk-core
 def _process_takes_package(self, original, updated, updates):
     # if target_for is set then we don't to digital client.
     targeted_for = updates.get('targeted_for', original.get('targeted_for'))
     if original[ITEM_TYPE] in {CONTENT_TYPE.TEXT, CONTENT_TYPE.PREFORMATTED} \
             and not (targeted_for or is_genre(original, BROADCAST_GENRE)):
         # check if item is in a digital package
         last_updated = updates.get(config.LAST_UPDATED, utcnow())
         package = self.takes_package_service.get_take_package(original)
         if not package:
             '''
             If type of the item is text or preformatted then item need to be sent to
             digital subscribers, so package the item as a take.
             '''
             package_id = self.takes_package_service.package_story_as_a_take(updated, {}, None)
             package = get_resource_service(ARCHIVE).find_one(req=None, _id=package_id)
         package_id = package[config.ID_FIELD]
         package_updates = self.process_takes(updates_of_take_to_be_published=updates,
                                              original_of_take_to_be_published=original,
                                              package=package)
         # If the original package is corrected then the next take shouldn't change it
         # back to 'published'
         preserve_state = package.get(ITEM_STATE, '') == CONTENT_STATE.CORRECTED and \
             updates.get(ITEM_OPERATION, ITEM_PUBLISH) == ITEM_PUBLISH
         self._set_updates(package, package_updates, last_updated, preserve_state)
         package_updates.setdefault(ITEM_OPERATION, updates.get(ITEM_OPERATION, ITEM_PUBLISH))
         self._update_archive(package, package_updates)
         package.update(package_updates)
         self.update_published_collection(published_item_id=package_id)
         self._import_into_legal_archive(package)
コード例 #5
0
    def get_broadcast_items_from_master_story(self, item, include_archived_repo=False):
        """Get the broadcast items from the master story.

        :param dict item: master story item
        :param include_archived_repo True if archived repo needs to be included in search, default is False
        :return list: returns list of broadcast items
        """
        if is_genre(item, BROADCAST_GENRE):
            return []

        ids = [str(item.get(config.ID_FIELD))]
        return list(self._get_broadcast_items(ids, include_archived_repo))
コード例 #6
0
ファイル: broadcast.py プロジェクト: will-in-wi/superdesk
    def get_broadcast_items_from_master_story(self, item):
        """
        Get the broadcast items from the master story.
        :param dict item: master story item
        :return list: returns list of broadcast items
        """
        if is_genre(item, BROADCAST_GENRE):
            return []

        ids = [str(item.get(config.ID_FIELD))]
        if self.takesService.get_take_package_id(item):
            ids.append(str(self.takesService.get_take_package_id(item)))

        return list(self._get_broadcast_items(ids))
コード例 #7
0
ファイル: resend.py プロジェクト: nistormihai/superdesk-core
    def _validate_subscribers(self, subscriber_ids, article):
        if not subscriber_ids:
            raise SuperdeskApiError.badRequestError(message='No subscribers selected!')

        query = {'$and': [{config.ID_FIELD: {'$in': list(subscriber_ids)}}, {'is_active': True}]}
        subscribers = list(get_resource_service('subscribers').get(req=None, lookup=query))

        if len(subscribers) == 0:
            raise SuperdeskApiError.badRequestError(message='No active subscribers found!')

        if is_genre(article, BROADCAST_GENRE):
            digital_subscribers = list(self.digital(subscribers))
            if len(digital_subscribers) > 0:
                raise SuperdeskApiError.badRequestError('Only wire subscribers can receive broadcast stories!')

        return subscribers
コード例 #8
0
    def _validate_link(self, target, target_id):
        """Validates the article to be linked.

        :param target: article to be linked
        :param target_id: id of the article to be linked
        :raises: SuperdeskApiError
        """
        if not target:
            raise SuperdeskApiError.notFoundError(message='Cannot find the target item with id {}.'.format(target_id))

        if target.get(EMBARGO):
            raise SuperdeskApiError.badRequestError("Takes can't be created for an Item having Embargo")

        if is_genre(target, BROADCAST_GENRE):
            raise SuperdeskApiError.badRequestError("Cannot add new take to the story with genre as broadcast.")

        if get_resource_service('published').is_rewritten_before(target['_id']):
            raise SuperdeskApiError.badRequestError(message='Article has been rewritten before !')
コード例 #9
0
ファイル: broadcast.py プロジェクト: akintolga/superdesk-core
    def remove_rewrite_refs(self, item):
        """
        Remove the rewrite references from the broadcast item if the re-write is spiked.
        :param dict item: Re-written article of the original story
        """
        if is_genre(item, BROADCAST_GENRE):
            return

        query = {
            'query': {
                'filtered': {
                    'filter': {
                        'and': [
                            {'term': {'genre.name': BROADCAST_GENRE}},
                            {'term': {'broadcast.rewrite_id': item.get(config.ID_FIELD)}}
                        ]
                    }
                }
            }
        }

        req = ParsedRequest()
        req.args = {'source': json.dumps(query)}
        broadcast_items = list(get_resource_service(SOURCE).get(req=req, lookup=None))

        for broadcast_item in broadcast_items:
            try:
                updates = {
                    'broadcast': broadcast_item.get('broadcast', {})
                }

                updates['broadcast']['rewrite_id'] = None

                if 'Re-written' in updates['broadcast']['status']:
                    updates['broadcast']['status'] = ''

                self._update_broadcast_status(broadcast_item, updates)
            except:
                logger.exception('Failed to remove rewrite id for the broadcast item {}'.
                                 format(broadcast_item.get(config.ID_FIELD)))
コード例 #10
0
ファイル: common.py プロジェクト: akintolga/superdesk-core
 def _is_take_item(self, item):
     """ Returns True if the item was a take
     """
     return item[ITEM_TYPE] != CONTENT_TYPE.COMPOSITE and \
         (not (item.get('targeted_for') or is_genre(item, BROADCAST_GENRE)))
コード例 #11
0
ファイル: archived.py プロジェクト: MiczFlor/superdesk-core
    def on_delete(self, doc):
        """
        Overriding to validate the item being killed is actually eligible for kill. Validates the following:
            1. Is item of type Text?
            2. Is item a Broadcast Script?
            3. Does item acts as a Master Story for any of the existing broadcasts?
            4. Is item available in production or part of a normal package?
            5. Is the associated Digital Story is available in production or part of normal package?
            6. If item is a Take then is any take available in production or part of normal package?
        :param doc: represents the article in archived collection
        :type doc: dict
        :raises SuperdeskApiError.badRequestError() if any of the above validation conditions fail.
        """

        bad_req_error = SuperdeskApiError.badRequestError

        id_field = doc[config.ID_FIELD]
        item_id = doc['item_id']

        doc['item_id'] = id_field
        doc[config.ID_FIELD] = item_id

        if doc[ITEM_TYPE] != CONTENT_TYPE.TEXT:
            raise bad_req_error(message='Only Text articles are allowed to Kill in Archived repo')

        if is_genre(doc, BROADCAST_GENRE):
            raise bad_req_error(message="Killing of Broadcast Items isn't allowed in Archived repo")

        if get_resource_service('archive_broadcast').get_broadcast_items_from_master_story(doc, True):
            raise bad_req_error(message="Can't kill as this article acts as a Master Story for existing broadcast(s)")

        if get_resource_service(ARCHIVE).find_one(req=None, _id=doc[GUID_FIELD]):
            raise bad_req_error(message="Can't Kill as article is still available in production")

        if is_item_in_package(doc):
            raise bad_req_error(message="Can't kill as article is part of a Package")

        takes_package_service = TakesPackageService()
        takes_package_id = takes_package_service.get_take_package_id(doc)
        if takes_package_id:
            if get_resource_service(ARCHIVE).find_one(req=None, _id=takes_package_id):
                raise bad_req_error(message="Can't Kill as the Digital Story is still available in production")

            req = ParsedRequest()
            req.sort = '[("%s", -1)]' % config.VERSION
            takes_package = list(self.get(req=req, lookup={'item_id': takes_package_id}))
            if not takes_package:
                raise bad_req_error(message='Digital Story of the article not found in Archived repo')

            takes_package = takes_package[0]
            if is_item_in_package(takes_package):
                raise bad_req_error(message="Can't kill as Digital Story is part of a Package")

            for takes_ref in takes_package_service.get_package_refs(takes_package):
                if takes_ref[RESIDREF] != doc[GUID_FIELD]:
                    if get_resource_service(ARCHIVE).find_one(req=None, _id=takes_ref[RESIDREF]):
                        raise bad_req_error(message="Can't Kill as Take(s) are still available in production")

                    take = list(self.get(req=None, lookup={'item_id': takes_ref[RESIDREF]}))
                    if not take:
                        raise bad_req_error(message='One of Take(s) not found in Archived repo')

                    if is_item_in_package(take[0]):
                        raise bad_req_error(message="Can't kill as one of Take(s) is part of a Package")

        doc['item_id'] = item_id
        doc[config.ID_FIELD] = id_field
コード例 #12
0
ファイル: common.py プロジェクト: vladnicoara/superdesk
    def update(self, id, updates, original):
        """
        Handles workflow of each Publish, Corrected and Killed.
        """
        try:
            user = get_user()
            last_updated = updates.get(config.LAST_UPDATED, utcnow())
            auto_publish = updates.pop('auto_publish', False)

            if original[ITEM_TYPE] == CONTENT_TYPE.COMPOSITE:
                self._publish_package_items(original, updates)

            queued_digital = False
            package = None

            if original[ITEM_TYPE] != CONTENT_TYPE.COMPOSITE:
                # if target_for is set the we don't to digital client.
                if not (updates.get('targeted_for', original.get('targeted_for')) or
                        is_genre(original, BROADCAST_GENRE)):
                    # check if item is in a digital package
                    package = self.takes_package_service.get_take_package(original)

                    if package:
                        queued_digital = self._publish_takes_package(package, updates, original, last_updated)
                    else:
                        '''
                        If type of the item is text or preformatted
                        then item need to be sent to digital subscribers.
                        So, package the item as a take.
                        '''
                        updated = copy(original)
                        updated.update(updates)

                        if original[ITEM_TYPE] in {CONTENT_TYPE.TEXT, CONTENT_TYPE.PREFORMATTED} and \
                                self.sending_to_digital_subscribers(updated):
                            # create a takes package
                            package_id = self.takes_package_service.package_story_as_a_take(updated, {}, None)
                            updates[LINKED_IN_PACKAGES] = updated[LINKED_IN_PACKAGES]
                            package = get_resource_service(ARCHIVE).find_one(req=None, _id=package_id)
                            queued_digital = self._publish_takes_package(package, updates, original, last_updated)

                # queue only text items
                media_type = None
                updated = deepcopy(original)
                updated.update(updates)
                if package:
                    media_type = SUBSCRIBER_TYPES.WIRE

                queued_wire = self.publish(doc=original, updates=updates, target_media_type=media_type)

                queued = queued_digital or queued_wire
                if not queued:
                    logger.exception('Nothing is saved to publish queue for story: {} for action: {}'.
                                     format(original[config.ID_FIELD], self.publish_type))

            self._update_archive(original=original, updates=updates, should_insert_into_versions=auto_publish)
            push_notification('item:publish', item=str(id), unique_name=original['unique_name'],
                              desk=str(original.get('task', {}).get('desk', '')),
                              user=str(user.get(config.ID_FIELD, '')))
        except SuperdeskApiError as e:
            raise e
        except KeyError as e:
            raise SuperdeskApiError.badRequestError(
                message="Key is missing on article to be published: {}".format(str(e)))
        except Exception as e:
            logger.exception("Something bad happened while publishing %s".format(id))
            raise SuperdeskApiError.internalError(message="Failed to publish the item: {}".format(str(e)))
コード例 #13
0
    def test_broadcast_content_if_genre_is_other_than_broadcast(self):
        content = {'genre': [{'name': 'Article', 'qcode': 'Article'}]}

        self.assertFalse(is_genre(content, BROADCAST_GENRE))
        self.assertTrue(is_genre(content, 'Article'))
コード例 #14
0
    def on_broadcast_master_updated(self,
                                    item_event,
                                    item,
                                    takes_package_id=None,
                                    rewrite_id=None):
        """
        This event is called when the master story is corrected, published, re-written, new take/re-opened
        :param str item_event: Item operations
        :param dict item: item on which operation performed.
        :param str takes_package_id: takes_package_id.
        :param str rewrite_id: re-written story id.
        """
        status = ''

        if not item or is_genre(item, BROADCAST_GENRE):
            return

        if item_event == ITEM_CREATE and takes_package_id:
            if RE_OPENS.lower() in str(item.get('anpa_take_key', '')).lower():
                status = 'Story Re-opened'
            else:
                status = 'New Take Created'

        elif item_event == ITEM_CREATE and rewrite_id:
            status = 'Master Story Re-written'
        elif item_event == ITEM_PUBLISH:
            status = 'Master Story Published'
        elif item_event == ITEM_CORRECT:
            status = 'Master Story Corrected'

        broadcast_items = self.get_broadcast_items_from_master_story(item)

        if not broadcast_items:
            return

        processed_ids = set()
        for broadcast_item in broadcast_items:
            try:
                if broadcast_item.get('lock_user'):
                    continue

                updates = {
                    'broadcast': broadcast_item.get('broadcast'),
                }

                if status:
                    updates['broadcast']['status'] = status

                if not updates['broadcast'][
                        'takes_package_id'] and takes_package_id:
                    updates['broadcast']['takes_package_id'] = takes_package_id

                if not updates['broadcast']['rewrite_id'] and rewrite_id:
                    updates['broadcast']['rewrite_id'] = rewrite_id

                if not broadcast_item.get(config.ID_FIELD) in processed_ids:
                    self._update_broadcast_status(broadcast_item, updates)
                    # list of ids that are processed.
                    processed_ids.add(broadcast_item.get(config.ID_FIELD))
            except:
                logger.exception(
                    'Failed to update status for the broadcast item {}'.format(
                        broadcast_item.get(config.ID_FIELD)))
コード例 #15
0
ファイル: archive_test.py プロジェクト: mscam/superdesk-core
    def test_broadcast_content(self):
        content = {
            'genre': [{'name': 'Broadcast Script', 'qcode': 'Broadcast Script'}]
        }

        self.assertTrue(is_genre(content, BROADCAST_GENRE))
コード例 #16
0
    def test_broadcast_content_if_genre_is_none(self):
        content = {"genre": None}

        self.assertFalse(is_genre(content, BROADCAST_GENRE))
コード例 #17
0
    def test_broadcast_content_if_genre_is_empty_list(self):
        content = {
            'genre': []
        }

        self.assertFalse(is_genre(content, BROADCAST_GENRE))
コード例 #18
0
    def test_broadcast_content(self):
        content = {
            'genre': [{'name': 'Broadcast Script', 'qcode': 'Broadcast Script'}]
        }

        self.assertTrue(is_genre(content, BROADCAST_GENRE))
コード例 #19
0
    def test_broadcast_content_if_genre_is_other_than_broadcast(self):
        content = {"genre": [{"name": "Article", "qcode": "Article"}]}

        self.assertFalse(is_genre(content, BROADCAST_GENRE))
        self.assertTrue(is_genre(content, "Article"))
コード例 #20
0
    def test_broadcast_content_if_genre_is_empty_list(self):
        content = {"genre": []}

        self.assertFalse(is_genre(content, BROADCAST_GENRE))
コード例 #21
0
    def test_broadcast_content_if_genre_is_none(self):
        content = {
            'genre': None
        }

        self.assertFalse(is_genre(content, BROADCAST_GENRE))
コード例 #22
0
ファイル: archived.py プロジェクト: bmg1919/superdesk-core
    def validate_delete_action(self, doc, allow_all_types=False):
        """Runs on delete of archive item.

        Overriding to validate the item being killed is actually eligible for kill. Validates the following:
            1. Is item of type Text?
            2. Is item a Broadcast Script?
            3. Does item acts as a Master Story for any of the existing broadcasts?
            4. Is item available in production or part of a normal package?
            5. Is the associated Digital Story is available in production or part of normal package?
            6. If item is a Take then is any take available in production or part of normal package?

        :param doc: represents the article in archived collection
        :type doc: dict
        :param allow_all_types: represents if different types of documents are allowed to be killed
        :type doc: bool
        :raises SuperdeskApiError.badRequestError() if any of the above validation conditions fail.
        """

        bad_req_error = SuperdeskApiError.badRequestError

        id_field = doc[config.ID_FIELD]
        item_id = doc['item_id']

        doc['item_id'] = id_field
        doc[config.ID_FIELD] = item_id

        if not allow_all_types and doc[ITEM_TYPE] != CONTENT_TYPE.TEXT:
            raise bad_req_error(message=_(
                'Only Text articles are allowed to be Killed in Archived repo')
                                )

        if is_genre(doc, BROADCAST_GENRE):
            raise bad_req_error(message=_(
                "Killing of Broadcast Items isn't allowed in Archived repo"))

        if get_resource_service(
                'archive_broadcast').get_broadcast_items_from_master_story(
                    doc, True):
            raise bad_req_error(message=_(
                "Can't kill as this article acts as a Master Story for existing broadcast(s)"
            ))

        if get_resource_service(ARCHIVE).find_one(req=None,
                                                  _id=doc[GUID_FIELD]):
            raise bad_req_error(message=_(
                "Can't Kill as article is still available in production"))

        if not allow_all_types and is_item_in_package(doc):
            raise bad_req_error(
                message=_("Can't kill as article is part of a Package"))

        takes_package_id = self._get_take_package_id(doc)
        if takes_package_id:
            if get_resource_service(ARCHIVE).find_one(req=None,
                                                      _id=takes_package_id):
                raise bad_req_error(message=_(
                    "Can't Kill as the Digital Story is still available in production"
                ))

            req = ParsedRequest()
            req.sort = '[("%s", -1)]' % config.VERSION
            takes_package = list(
                self.get(req=req, lookup={'item_id': takes_package_id}))
            if not takes_package:
                raise bad_req_error(message=_(
                    'Digital Story of the article not found in Archived repo'))

            takes_package = takes_package[0]
            if not allow_all_types and is_item_in_package(takes_package):
                raise bad_req_error(message=_(
                    "Can't kill as Digital Story is part of a Package"))

            for takes_ref in self._get_package_refs(takes_package):
                if takes_ref[RESIDREF] != doc[GUID_FIELD]:
                    if get_resource_service(ARCHIVE).find_one(
                            req=None, _id=takes_ref[RESIDREF]):
                        raise bad_req_error(message=_(
                            "Can't Kill as Take(s) are still available in production"
                        ))

                    take = list(
                        self.get(req=None,
                                 lookup={'item_id': takes_ref[RESIDREF]}))
                    if not take:
                        raise bad_req_error(message=_(
                            'One of Take(s) not found in Archived repo'))

                    if not allow_all_types and is_item_in_package(take[0]):
                        raise bad_req_error(message=_(
                            "Can't kill as one of Take(s) is part of a Package"
                        ))

        doc['item_id'] = item_id
        doc[config.ID_FIELD] = id_field
コード例 #23
0
 def _is_take_item(self, item):
     """Returns True if the item was a take."""
     return item[ITEM_TYPE] != CONTENT_TYPE.COMPOSITE and \
         (not (self.is_targeted(item) or is_genre(item, BROADCAST_GENRE)))
コード例 #24
0
ファイル: common.py プロジェクト: copyfun/superdesk
    def update(self, id, updates, original):
        """
        Handles workflow of each Publish, Corrected and Killed.
        """
        try:
            user = get_user()
            last_updated = updates.get(config.LAST_UPDATED, utcnow())
            auto_publish = updates.pop('auto_publish', False)

            if original[ITEM_TYPE] == CONTENT_TYPE.COMPOSITE:
                self._publish_package_items(original, updates)

            queued_digital = False
            package = None

            if original[ITEM_TYPE] != CONTENT_TYPE.COMPOSITE:
                # if target_for is set the we don't to digital client.
                if not (updates.get('targeted_for', original.get('targeted_for')) or
                        is_genre(original, BROADCAST_GENRE)):
                    # check if item is in a digital package
                    package = self.takes_package_service.get_take_package(original)

                    if package:
                        queued_digital = self._publish_takes_package(package, updates, original, last_updated)
                    else:
                        '''
                        If type of the item is text or preformatted
                        then item need to be sent to digital subscribers.
                        So, package the item as a take.
                        '''
                        updated = copy(original)
                        updated.update(updates)

                        if original[ITEM_TYPE] in {CONTENT_TYPE.TEXT, CONTENT_TYPE.PREFORMATTED} and \
                                self.sending_to_digital_subscribers(updated):

                            # create a takes package
                            package_id = self.takes_package_service.package_story_as_a_take(updated, {}, None)
                            insert_into_versions(id_=package_id)

                            updates[LINKED_IN_PACKAGES] = updated[LINKED_IN_PACKAGES]
                            package = get_resource_service(ARCHIVE).find_one(req=None, _id=package_id)
                            queued_digital = self._publish_takes_package(package, updates, original, last_updated)

                # queue only text items
                media_type = None
                updated = deepcopy(original)
                updated.update(updates)
                if package:
                    media_type = SUBSCRIBER_TYPES.WIRE

                queued_wire = self.publish(doc=original, updates=updates, target_media_type=media_type)

                queued = queued_digital or queued_wire
                if not queued:
                    logger.error('Nothing is saved to publish queue for story: {} for action: {}'.
                                 format(original[config.ID_FIELD], self.publish_type))

            self._update_archive(original=original, updates=updates, should_insert_into_versions=auto_publish)
            push_notification('item:publish', item=str(id), unique_name=original['unique_name'],
                              desk=str(original.get('task', {}).get('desk', '')),
                              user=str(user.get(config.ID_FIELD, '')))
        except SuperdeskApiError as e:
            raise e
        except KeyError as e:
            raise SuperdeskApiError.badRequestError(
                message="Key is missing on article to be published: {}".format(str(e)))
        except Exception as e:
            logger.exception("Something bad happened while publishing %s".format(id))
            raise SuperdeskApiError.internalError(message="Failed to publish the item: {}".format(str(e)))