diff --git a/README b/README index b25e836..3b83e67 100644 --- a/README +++ b/README @@ -28,7 +28,6 @@ python3 main.py #### TODOS (next 26): -TODO-23: when moving a book in a series (which is part of 2 series), do we pop-up offer to move parent/child series orders as well to match (think Thomas Covenant) TODO-24: get this into docker (as per TODO above) gunicorn and it seems easy enough: https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on-ubuntu-18-04 diff --git a/main.py b/main.py index 77923b0..3194305 100644 --- a/main.py +++ b/main.py @@ -137,17 +137,23 @@ class Book(db.Model): return 1 def MoveBookInSeries( self, series_id, amt ): - if self.IsParent(): - tmp_book=book_schema.dump(self) - for book in tmp_book['child_ref']: - tmp_bid=GetBookIdFromBookSubBookLinkByIdAndSubBookNum( self.id, book['sub_book_num'] ) - bsl=Book_Series_Link.query.filter( Book_Series_Link.book_id==tmp_bid, Book_Series_Link.series_id==series_id ).all() + # if parent book, move all sub books instead + try: + if self.IsParent(): + tmp_book=book_schema.dump(self) + for book in tmp_book['child_ref']: + tmp_bid=GetBookIdFromBookSubBookLinkByIdAndSubBookNum( self.id, book['sub_book_num'] ) + bsl=Book_Series_Link.query.filter( Book_Series_Link.book_id==tmp_bid, Book_Series_Link.series_id==series_id ).all() + bsl[0].book_num=bsl[0].book_num+amt + else: + bsl=Book_Series_Link.query.filter( Book_Series_Link.book_id==self.id, Book_Series_Link.series_id==series_id ).all() bsl[0].book_num=bsl[0].book_num+amt - else: - bsl=Book_Series_Link.query.filter( Book_Series_Link.book_id==self.id, Book_Series_Link.series_id==series_id ).all() - bsl[0].book_num=bsl[0].book_num+amt - db.session.commit() - return + db.session.commit() + return + except SQLAlchemyError as e: + st.SetAlert( "danger" ) + st.SetMessage( e.orig ) + return redirect( '/series/{}'.format(series_id) ) def __repr__(self): return "".format(self.id, self.author, self.title, self.year_published, self.rating, self.condition, self.owned, self.covertype, self.notes, self.blurb, self.created, self.modified, self.publisher, self.genre, self.parent ) @@ -255,63 +261,68 @@ def books_for_loan(id): InDBox=0 return render_template("books_for_loan.html", books=books, loan_id=id, InDBox=InDBox) +def CalcMoveForBookInSeries( id, bid, dir ): + book1 = Book.query.get(bid) + + # if parent book, then up needs first sub book, if down then need last sub book (as parent book does not have a book_num in a series, its sub books do) + if book1.IsParent(): + if dir == "up": + tmp_bid = GetBookIdFromBookSubBookLinkByIdAndSubBookNum( book1.id, book1.FirstSubBookNum() ) + else: + tmp_bid = GetBookIdFromBookSubBookLinkByIdAndSubBookNum( book1.id, book1.LastSubBookNum() ) + moving_series_book_num = GetBookNumBySeriesAndBookId( id, tmp_bid ) + else: + moving_series_book_num = GetBookNumBySeriesAndBookId( id, book1.id ) + # moving_series_book_num is the book_num of the book in the series we are really moving (adjusted for parent/sub book if needed) + + if dir == "up": + swapping_with_book_num = moving_series_book_num-1 + else: + swapping_with_book_num = moving_series_book_num+1 + # swapping_with_book_num is the book_num of the book in the series we are going to swap with (notionally next/prev book in series) + + tmp_bid = GetBookIdFromSeriesByBookNum( id, swapping_with_book_num ) + # okay, if tmp_bid is None, then there is no book we are swapping + # with (rare case of moving say book 7 of a series of 10, and we + # don't have details on book 6 or 8... + if tmp_bid == None: + if dir == "up": + book1.MoveBookInSeries( id, -1 ) + else: + book1.MoveBookInSeries( id, 1 ) + else: + book2 = Book.query.get( tmp_bid ) + + # if book2 is a sub book, then we need its parent as book2 instead, as we have to move the whole book as one + if book2.IsChild(): + book2 = Book.query.get( book2.parent[0].id ) + + # By here: book1 is parent or normal book we are swapping with book2 which is parent or normal book + b1_numsb = book1.NumSubBooks() + b2_numsb = book2.NumSubBooks() + if dir == "up": + b1_move_by=-b2_numsb + b2_move_by=b1_numsb + else: + b1_move_by=b2_numsb + b2_move_by=-b1_numsb + + # By here: b{1,2}_move_by is the sign & amount we are moving the relevant book (and its sub-books by). If it is a normal book, + # then its by +/-1, but if it is a parent book, then its +/- the num of sub_books as they all have to move too + + # MoveBookInSeries -> moves the book and its sub_books + book1.MoveBookInSeries( id, b1_move_by ) + book2.MoveBookInSeries( id, b2_move_by ) + @app.route("/books_for_series/", methods=["GET", "POST"]) def books_for_series(id): if request.method == 'POST': if 'move_button' in request.form: # split form's pressed move_button to yield: dir ("up" or "down") and bid = book_id of book dir, bid = request.form['move_button'].split('-') - book1 = Book.query.get(bid) - # if parent book, then up needs first sub book, if down then need last sub book (as parent book does not have a book_num in a series, its sub books do) - if book1.IsParent(): - if dir == "up": - tmp_bid = GetBookIdFromBookSubBookLinkByIdAndSubBookNum( book1.id, book1.FirstSubBookNum() ) - else: - tmp_bid = GetBookIdFromBookSubBookLinkByIdAndSubBookNum( book1.id, book1.LastSubBookNum() ) - moving_series_book_num = GetBookNumBySeriesAndBookId( id, tmp_bid ) - else: - moving_series_book_num = GetBookNumBySeriesAndBookId( id, book1.id ) - # moving_series_book_num is the book_num of the book in the series we are really moving (adjusted for parent/sub book if needed) - - if dir == "up": - swapping_with_book_num = moving_series_book_num-1 - else: - swapping_with_book_num = moving_series_book_num+1 - # swapping_with_book_num is the book_num of the book in the series we are going to swap with (notionally next/prev book in series) - - tmp_bid = GetBookIdFromSeriesByBookNum( id, swapping_with_book_num ) - # okay, if tmp_bid is None, then there is no book we are swapping - # with (rare case of moving say book 7 of a series of 10, and we - # don't have details on book 6 or 8... - if tmp_bid == None: - if dir == "up": - book1.MoveBookInSeries( id, -1 ) - else: - book1.MoveBookInSeries( id, 1 ) - else: - book2 = Book.query.get( tmp_bid ) - - # if book2 is a sub book, then we need its parent as book2 instead, as we have to move the whole book as one - if book2.IsChild(): - book2 = Book.query.get( book2.parent[0].id ) - - # By here: book1 is parent or normal book we are swapping with book2 which is parent or normal book - b1_numsb = book1.NumSubBooks() - b2_numsb = book2.NumSubBooks() - if dir == "up": - b1_move_by=-b2_numsb - b2_move_by=b1_numsb - else: - b1_move_by=b2_numsb - b2_move_by=-b1_numsb - - # By here: b{1,2}_move_by is the sign & amount we are moving the relevant book (and its sub-books by). If it is a normal book, - # then its by +/-1, but if it is a parent book, then its +/- the num of sub_books as they all have to move too - - # MoveBookInSeries -> moves the book and its sub_books - book1.MoveBookInSeries( id, b1_move_by ) - book2.MoveBookInSeries( id, b2_move_by ) + for bsl in book1.bsl: + CalcMoveForBookInSeries( bsl.series_id, bid, dir ) books = Book.query.join(Book_Series_Link).filter(Book_Series_Link.series_id==id).all() series = Series.query.get(id) @@ -362,7 +373,6 @@ def subbooks_for_book(id): ################################################################################ @app.route("/remove_subbook", methods=["POST"]) def remove_sub_book(): - print("DDP: ADD SQL HERE TO DO THE DELETE - try/except") try: db.engine.execute("delete from book_sub_book_link where book_id = {} and sub_book_id = {}".format( request.form['rem_sub_parent_id'], request.form['rem_sub_sub_book_id']) ) db.session.commit()