Exemplo n.º 1
0
def __insert_contributions(book, form, session):
    """
    Insert the contributions in the form to the session. No commits will take
    place.
    """
    from flask_login import current_user

    # Create the Contributors
    authors = __create_bookperson(form.authors.data)
    illustrators = __create_bookperson(form.illustrators.data)
    editors = __create_bookperson(form.editors.data)
    translators = __create_bookperson(form.translators.data)

    author_role = Role.get_preset_role("Author")
    illus_role = Role.get_preset_role("Illustrator")
    editor_role = Role.get_preset_role("Editor")
    trans_role = Role.get_preset_role("Translator")

    # Assign participation
    for author in authors:
        author_part = BookContribution(book=book,
                                       contributor=author,
                                       role=author_role,
                                       creator=current_user)
        if not author.active:
            author.active = True
        session.add(author)
        session.add(author_part)

    for illustrator in illustrators:
        illus_part = BookContribution(book=book,
                                      contributor=illustrator,
                                      role=illus_role,
                                      creator=current_user)
        if not illustrator.active:
            illustrator.active = True
        session.add(illustrator)
        session.add(illus_part)

    for editor in editors:
        editor_part = BookContribution(book=book,
                                       contributor=editor,
                                       role=editor_role,
                                       creator=current_user)
        if not editor.active:
            editor.active = True
        session.add(editor)
        session.add(editor_part)

    for translator in translators:
        translator_part = BookContribution(book=book,
                                           contributor=translator,
                                           role=trans_role,
                                           creator=current_user)
        if not translator.active:
            translator.active = True
        session.add(translator)
        session.add(translator_part)
Exemplo n.º 2
0
def edit_book():
    def contribution_exists(all_contribs, role_id, person):
        """
        Check if the given person contributed for the given role in all the
        contributions related to the present book being edited.

        Where
        
        `all_contribs` is all the BookContribution records for the book being
        edited.

        person is an instance of librarian.utils.Person.

        Returns the BookContribution object if it exists, else False.
        """
        the_contribution = [
            contrib for contrib in all_contribs
            if (contrib.role_id == role_id
                and contrib.contributor.firstname == person.firstname
                and contrib.contributor.lastname == person.lastname)
        ]

        if len(the_contribution) > 1:
            raise InvalidRecordState(
                "uniqueness of contribution role + person + book %s" % spam)

        if the_contribution:
            return the_contribution[0]
        else:
            return False

    def edit_contrib(book, all_contribs, role, submitted_persons):
        """
        Adds all new contributors to the session and deletes all removed
        contributors to the session.

        Where `submitted_persons` is the data straight out of the form (hence it
        is a JSON string), `all_contribs` are all the active contributions in
        the book as recorded in the DB (pre-edit).
        """
        app.logger.debug("considering role %s" % role)
        parsons = json.loads(submitted_persons)
        form_records = set()

        # Create or load all the contributions mentioned in the form.
        for p in parsons:
            ce = contribution_exists(all_contribs, role.id, Person(**p))
            if ce is not False:
                form_records.add(ce)
            else:
                contributor_record = get_or_create(Contributor,
                                                   will_commit=False,
                                                   firstname=p["firstname"],
                                                   lastname=p["lastname"],
                                                   creator=current_user)
                app.logger.debug("got contributor record %s" %
                                 contributor_record)
                app.logger.debug("will attach role %s" % role)

                if not contributor_record.active:
                    contributor_record.active = True

                contribution = BookContribution(book=book,
                                                contributor=contributor_record,
                                                role=role,
                                                creator=current_user)
                db.session.add(contribution)
                form_records.add(contribution)

        recorded_contribs = set([
            contrib for contrib in all_contribs if contrib.role.id == role.id
        ])

        app.logger.debug("recorded contribs for %s %s" %
                         (role, recorded_contribs))
        app.logger.debug("form records %s" % form_records)
        deletables = recorded_contribs - form_records
        app.logger.debug("The deletables %s" % deletables)

        for d in deletables:
            d.active = False

            other_contrib = (BookContribution.query.filter(
                BookContribution.contributor_id == d.contributor_id).filter(
                    or_(BookContribution.book_id != book.id,
                        BookContribution.role_id != d.role_id)).filter(
                            BookContribution.active).first())
            app.logger.debug(
                "Contributor %s has another contribution %s (checked from %s)"
                % (d.contributor_id, other_contrib, role.name))

            if other_contrib is None:
                app.logger.debug("Deactivating %s" % d)
                d.contributor.active = False

    from flask_login import current_user

    form = EditBookForm(request.form)
    app.logger.info(str(form))
    app.logger.debug(form.debug_validate())

    if form.validate_on_submit():
        book_id = int(form.book_id.data)
        try:
            # Update records in books table
            genre = get_or_create(Genre,
                                  will_commit=False,
                                  session=db.session,
                                  name=form.genre.data,
                                  creator=current_user)
            publisher = get_or_create(BookCompany,
                                      will_commit=False,
                                      name=form.publisher.data,
                                      creator=current_user)
            book = db.session.query(Book).filter(Book.id == book_id).first()
            book.isbn = form.isbn.data
            book.title = form.title.data
            book.publish_year = form.year.data
            book.genre_id = genre.id
            book.publisher_id = publisher.id

            # Get all the contributions for this book
            all_contribs = (BookContribution.query.filter(
                BookContribution.book_id ==
                book_id).filter(BookContribution.active).filter(
                    BookContribution.contributor_id == Contributor.id).filter(
                        Contributor.active).all())

            edit_contrib(book, all_contribs, Role.get_preset_role("Author"),
                         form.authors.data)
            r_illustrator = Role.get_preset_role("Illustrator")
            edit_contrib(book, all_contribs, r_illustrator,
                         form.illustrators.data)
            edit_contrib(book, all_contribs, Role.get_preset_role("Editor"),
                         form.editors.data)
            edit_contrib(book, all_contribs,
                         Role.get_preset_role("Translator"),
                         form.translators.data)

            db.session.commit()
            return "Accepted", 200
        except IntegrityError, ierr:
            db.session.rollback()
            app.logger.error("Integrity Error occurred")
            app.logger.exception(traceback.format_exc())
            return "IntegrityError", 409
        except Exception as ex:
            db.session.rollback()
            app.logger.error("error except. traceback follows:")
            import traceback
            traceback.print_exc()
            return "Unknown error", 500