示例#1
0
文件: tasks.py 项目: quru/qis
def burst_pdf(**kwargs):
    """
    A task that creates a sub-folder next to a PDF file and extracts all
    pages from the PDF as PNG files into the sub-folder.
    """
    from flask_app import app
    from filesystem_manager import get_abs_path, get_burst_path, get_file_data
    from filesystem_manager import delete_dir, make_dirs, path_exists
    from filesystem_sync import delete_folder
    from imagemagick import imagemagick_burst_pdf
    from models import Folder
    from util import get_file_extension

    (src,) = _extract_parameters(["src"], **kwargs)
    burst_folder_rel = get_burst_path(src)

    # Ensure src is a PDF
    if get_file_extension(src) not in app.config["PDF_FILE_TYPES"]:
        app.log.warn("Cannot burst non-PDF file: " + src)
        return

    # See if the burst folder already exists (in the database and on disk)
    db_folder = app.data_engine.get_folder(folder_path=burst_folder_rel)
    if db_folder is not None and db_folder.status == Folder.STATUS_ACTIVE:
        # Wipe the folder, old images, data, and uncache the old images
        delete_folder(db_folder, None, app.data_engine, None, app.log)
        deleted_ids = app.data_engine.list_image_ids(db_folder)
        for image_id in deleted_ids:
            app.image_engine._uncache_image_id(image_id)

    # See if the burst folder already exists (just on disk)
    if path_exists(burst_folder_rel, require_directory=True):
        # Wipe the folder and old images
        delete_dir(burst_folder_rel, recursive=True)

    # Create the burst folder and burst
    pdf_data = get_file_data(src)
    if pdf_data is not None:
        make_dirs(burst_folder_rel)
        burst_folder_abs = get_abs_path(burst_folder_rel)
        if not imagemagick_burst_pdf(pdf_data, burst_folder_abs, app.config["PDF_BURST_DPI"]):
            app.log.warn("Failed to burst PDF: " + src)
    else:
        app.log.warn("Cannot burst PDF, file not found: " + src)
示例#2
0
def create_folder(rel_path, user_account, data_manager, permissions_manager, logger):
    """
    Creates a folder on disk and the associated database record.
    The folder path cannot be blank and should not already exist.

    The user account must have Create Folder permission for the parent folder,
    or alternatively have the file admin system permission.

    This method creates and commits its own separate database connection
    so that the operation is atomic.

    Returns the new folder object.

    Raises an AlreadyExistsError if the folder path already exists.
    Raises an OSError if the new folder cannot be created.
    Raises a ValueError if the folder path is invalid.
    Raises a DBError for database errors.
    Raises a SecurityError if the current user does not have sufficient
    permission to create the folder, or if the folder path is outside of
    IMAGES_BASE_DIR.
    """
    db_session = data_manager.db_get_session()
    success = False
    try:
        _validate_path_chars(rel_path)
        rel_path = filepath_normalize(rel_path)
        rel_path = _secure_folder_path(
            rel_path,
            True,
            app.config['ALLOW_UNICODE_FILENAMES']
        )

        # Don't allow blank path
        if strip_seps(rel_path) == '':
            raise ValueError('Folder path to create cannot be empty')
        # Check for existing (physical) path
        if path_exists(rel_path):
            raise AlreadyExistsError('Path already exists: ' + rel_path)

        # Check permissions for the (nearest existing) db parent folder
        if user_account:
            db_parent_folder = _get_nearest_parent_folder(
                rel_path, data_manager, db_session
            )
            permissions_manager.ensure_folder_permitted(
                db_parent_folder,
                FolderPermission.ACCESS_CREATE_FOLDER,
                user_account
            )

        # Create the physical folder
        filesystem_manager.make_dirs(rel_path)

        # Update the database
        db_folder = auto_sync_existing_folder(
            rel_path,
            data_manager,
            _db_session=db_session
        )

        # OK!
        logger.info(
            'Disk folder %s created by %s' %
            (rel_path, user_account.username if user_account else 'System')
        )
        success = True
        return db_folder

    finally:
        # Commit or rollback database
        try:
            if success:
                db_session.commit()
            else:
                db_session.rollback()
        finally:
            db_session.close()