def get_book_pdf(book_id, index): """ TODO: I'm a huge method that isn't easy to read Please, refactor me ASAP """ items = item_index["id"].get(book_id, None) if (index <= 0): flask.abort(http.client.BAD_REQUEST, "Param index should be positive number") if items is None: flask.abort(http.client.NOT_FOUND, "Book with id {book_id} was not found".format( book_id=book_id )) item = utils.first(items) item_url = item.get("url") or set() request_path = flask.request.script_root + flask.request.path request_url_production = "https://" + config.www.app_domain_production + request_path if ( (book_id != item.id()) or (request_url_production not in item_url) or not utils.is_url_self_served(request_url_production, item) ): flask.abort(404, "Book with id {book_id} isn't available for download".format( book_id=book_id )) file_name, file_size = utils.get_file_info_from_url(request_url_production, item) #filenames start from slash, trimming it pdf_full_path = os.path.join(config.www.elibrary_dir, file_name[1:]) if not os.path.isfile(pdf_full_path): message = "Item {book_id} metadata is wrong: file for url {rel_url} is missing".format( book_id=book_id, rel_url=request_url_production ) logging.error(message) flask.abort(http.client.INTERNAL_SERVER_ERROR, message) logging.info("Sending pdf file: {pdf_full_path}".format( pdf_full_path=pdf_full_path )) if config.working_mode == WorkingMode.Unittest: #using send_file in unittest mode causes ResourceWarning due to unclosed file response = flask.make_response("SOME_BINARY_PDF_LIKE_DATA") response.headers["Content-Type"] = "application/pdf" else: #native send_file as_attrachment parameter works incorrectly with unicode data #adding corrent Content-Disposition header manually response = flask.make_response(flask.send_file(pdf_full_path)) basename = os.path.basename(pdf_full_path) response.headers["Content-Disposition"] = \ "attachment;" \ "filename*=UTF-8''{utf_filename}".format( utf_filename=urlparse.quote(basename) ) return response
def check_url_validity(item, errors): """ Checks url for validity """ url = item.get("url") item_id = item.get("id") if url is None: return for number, single_url in enumerate(url): if not utils.is_url_valid(single_url, item): errors.add("Field url with value [{single_url}] and number {number} is wrong".format( single_url=single_url, number=number )) if not utils.is_url_self_served(single_url, item): continue match = utils.SELF_SERVED_URL_REGEXP.match(single_url) if not match: errors.add("Self served url [{single_url}] doesn't match SELF_SERVED_URL_REGEXP".format( single_url=single_url )) continue if (match.group("item_id") != item_id): errors.add("Wrong item_id specified in self-served url") continue single_filename, single_filesize = utils.get_file_info_from_url(single_url, item) metadata = utils.extract_metadata_from_file(single_filename) owners = metadata.get("owner").split("+") if not owners: errors.add("Owner specification expected for self-served url #{number} (url={url}, filename={filename})".format( number=number, url=single_url, filename=single_filename )) continue for owner in owners: owner_fullname = config.parser.bookkeepers.get(owner) if owner_fullname: annotation = item.get("annotation") if ( (not annotation) or (owner_fullname not in annotation) ): errors.add("Owner fullname ({owner_fullname}) should be present in annotation".format( owner_fullname=owner_fullname ))
def validate_url_validity(item, errors): """ Checks url for validity """ url = item.get("url") item_id = item.get("id") if url is None: return for number, single_url in enumerate(url): if not utils.is_url_valid(single_url, item): errors.add("Field url with value [{single_url}] and number {number} is wrong".format( single_url=single_url, number=number )) if not utils.is_url_self_served(single_url, item): continue match = utils.SELF_SERVED_URL_REGEXP.match(single_url) if not match: errors.add("Self served url [{single_url}] doesn't match SELF_SERVED_URL_REGEXP".format( single_url=single_url )) continue if (match.group("item_id") != item_id): errors.add("Wrong item_id specified in self-served url") continue single_filename, single_filesize = utils.get_file_info_from_url(single_url, item) metadata = utils.extract_metadata_from_file(single_filename) owners = metadata.get("owner").split("+") if not owners: errors.add("Owner specification expected for self-served url #{number} (url={url}, filename={filename})".format( number=number, url=single_url, filename=single_filename )) continue for owner in owners: owner_fullname = config.parser.bookkeepers.get(owner) if owner_fullname: note = item.get("note") if ( (not note) or (owner_fullname not in note) ): errors.add("Owner fullname ({owner_fullname}) should be present in note".format( owner_fullname=owner_fullname ))
def from_url(single_url, item): if utils.is_url_self_served(single_url, item): return Availability.AvailableHere else: return Availability.AvailableElsewhere