Ejemplo n.º 1
0
    def apply_changes(self, lecture: Lecture,
                      changes: CollectedChanges) -> FetchResult:
        result = FetchResult.create(
            fetched=changes.unchanged,
            errored=changes.errored,
            next_start_index=changes.next_start_index,
        )

        # Build amendement -> position map
        moved_amendements = {
            amendement: changes.position_changes[amendement.num]
            for amendement in lecture.amendements
            if amendement.num in changes.position_changes
        }

        # Reset positions first, so that we never have two with the same position
        # (which would trigger an integrity error due to the unique constraint)
        for amendement in moved_amendements:
            amendement.position = None
        DBSession.flush()

        # Create amendements in numerical order, because a "sous-amendement"
        # must always be created after its parent
        for create_action in sorted(changes.creates, key=attrgetter("num")):
            result += create_action.apply(lecture)

        # Update amendements
        for update_action in changes.updates:
            result += update_action.apply(lecture)

        # Apply new amendement positions
        for amendement, position in moved_amendements.items():
            if amendement.position != position:
                amendement.position = position

        DBSession.flush()

        # Was it the last batch?
        if changes.next_start_index is None:
            lecture.reset_fetch_progress()

        return result
Ejemplo n.º 2
0
    def _fetch(self, lecture: Lecture, dry_run: bool = False) -> FetchResult:
        created: Set[int] = set()
        amendements: List[Amendement] = []

        # Remember previous positions and reset them
        old_positions = {}
        for amendement in lecture.amendements:
            old_positions[amendement.num] = amendement.position
            amendement.position = None

        try:
            amendements_created = self._fetch_and_parse_all(lecture=lecture,
                                                            dry_run=dry_run)
        except NotFound:
            return FetchResult.create(fetched=set(), created=set())

        for amendement, created_ in amendements_created:
            if created_:
                created.add(amendement.num)
            amendements.append(amendement)

        processed_amendements = list(
            self._process_amendements(amendements=amendements,
                                      lecture=lecture))
        lecture.reset_fetch_progress()

        # Log amendements no longer discussed
        for amdt in lecture.amendements:
            if amdt.position is None and old_positions.get(
                    amdt.num) is not None:
                logger.info("Amendement %s retiré de la discussion", amdt.num)

        return FetchResult.create(
            fetched={amdt.num
                     for amdt in processed_amendements},
            created=created)