Ejemplo n.º 1
0
def _on_share_paths_cb(paths,
                       share_links,
                       error_info='',
                       move=False,
                       save_to_clipboard=True,
                       context=''):
    '''
    Callback to be called after
    processing of 'share_path' shell command

    @param paths Filesystem paths [list]
    @param share_links Links URLs [list] or None if links getting failed
    '''

    if share_links:
        if save_to_clipboard:
            Application.show_tray_notification(
                tr("URL(s) for downloading copied to clipboard"),
                tr("Sharing"))
        else:
            params.ipc_ws_server.on_paths_links(paths, share_links, context,
                                                move)
    elif paths:
        try:
            share_names = list(map(lambda p: get_relpath(p)[1], paths))
            signals.share_path_failed.emit(share_names)
        except Exception as e:
            logger.warning(
                "on_share_paths_cb, share_path_failed exception: %s", e)

        Application.show_tray_notification(
            tr("Sharing {} file(s) failed: {}").format(len(paths), error_info),
            tr("Sharing"))
Ejemplo n.º 2
0
def show_copying_failed(path):
    '''
    Shows message when copying of file/dir into sync directory failed

    @param path Filesystem path [unicode]
    '''

    name = op.basename(path)
    Application.show_tray_notification(
        tr("Failed to copy '{}' into sync directory").format(name),
        tr("Shell"))
Ejemplo n.º 3
0
def block_path_slot(paths):
    '''
    Callback to be called after
    processing 'block_path' shell command

    @param path Filesystem path [unicode]
    '''

    # Request share cancelling
    if cancel_sharing(paths):
        Application.show_tray_notification(tr("Sharing cancelled"),
                                           tr("Sharing"))
    else:
        Application.show_tray_notification(tr("Failed to cancel path sharing"),
                                           tr("Sharing"))
Ejemplo n.º 4
0
def _on_open_link_cb(path, share_link):
    '''
    Callback to be called after
    processing 'open_link' shell command

    @param path Filesystem path [unicode]
    @param share_link Link URL [unicode] or None if link getting failed
    '''

    # Open URL in the web browser (if any)
    if share_link:
        webbrowser.open_new(share_link)
    else:
        name = op.basename(path)
        Application.show_tray_notification(
            tr("Failed to share file: {}").format(name), tr("Sharing"))
Ejemplo n.º 5
0
def _check_free_space(path, root, move, is_file):
    if is_file:
        size = op.getsize(path)
    else:
        size = get_dir_size(path)
    if move:
        path_list = path.split('/')
        root_list = root.split('/')
        # check if we have same drive for move
        if path_list[0] == root_list[0]:
            return True

    approx_total_size = size * 2 + size * 0.1  # size for files, copies, signs
    if get_free_space(root) < approx_total_size:
        logger.warning("Not enough disk space for  (moving) '%s'", path)
        msg = tr("Not enough disk space for copying (moving)\n{} to {}.\n"
                 "Please clean disk")
        Application.show_tray_notification(msg.format(path, root),
                                           tr("Sharing"))
        return False

    return True
Ejemplo n.º 6
0
def _on_email_link_cb(paths, share_links, error_info=''):
    '''
    Processes 'email_link' shell command

    @param path Filesystem path [unicode]
    @param share_link Link URL [unicode] or None if link getting failed
    '''

    # Pass share link to default mail client as 'mailto' protocol (if any)
    if share_links:
        subject = "Link for shared files/folders by Pvtbox"
        body = "Shared by Pvtbox:\r\n"
        for path, link in zip(paths, share_links):
            _, share_name = get_relpath(path)
            body += "{} - {}\r\n".format(share_name, link)
        mailto_url = "mailto:?subject={}&body={}" \
            .format(quote(subject.encode("utf-8")),
                    quote(body.encode("utf-8")))
        webbrowser.open_new(mailto_url)
    else:
        share_names = list(map(lambda p: get_relpath(p)[1], paths))
        signals.share_path_failed.emit(share_names)
        Application.show_tray_notification(
            tr("Failed to share {} file(s)").format(len(paths)), tr("Sharing"))
Ejemplo n.º 7
0
def add_to_sync_dir(paths, move, callback):
    '''
    Copies given paths (files or directories) into sync directory.
    If destination path exists, new name in sync directory will be created

    @param paths to be copied [list]
    '''

    # Get sync directory path
    root = params.cfg.sync_directory
    if not root:
        logger.warning("Sync directory is not set")
        return

    logger.debug("Copying %d paths", len(paths))
    signals.show.emit()
    result_paths = []
    offline_paths = []
    online_paths = []
    for path in paths:
        is_file = op.isfile(path)
        path = FilePath(path)
        # Path is in sync directory already
        if path in FilePath(root):
            logger.debug("Path '%s' is in sync directory '%s' already", path,
                         root)
            result_paths.append(path)
            if is_file and not move:
                if path.endswith(FILE_LINK_SUFFIX):
                    online_paths.append(path)
                else:
                    offline_paths.append(path)
            continue

        if not op.exists(path.longpath):
            logger.warning(
                "Path requested for copying does not exist "
                "or not enough rights "
                "are granted to access it: '%s'", FilePath(path))
            Application.show_tray_notification(
                tr("Failed to copy to synchronized directory. Specified path "
                   "does not exist."), tr("Sharing"))
            continue

        basename = op.basename(path)
        destname = get_next_name(FilePath(op.join(root, basename)).longpath)

        if not _check_free_space(path, root, move, is_file):
            continue

        file_dir = 'file' if is_file else 'dir'
        logger.debug("Copying (moving) %s '%s' into sync directory...",
                     file_dir, path)

        # Emit corresponding signal
        signals.copying_started.emit(path)

        # Copy or move file or directory into sync directory
        try:
            if move:
                shutil.move(path, destname)
            elif is_file:
                copy_file(path, destname)
            else:
                shutil.copytree(path, destname)
        except Exception as e:
            logger.error("Failed to copy (move) '%s' into sync directory (%s)",
                         path, e)
            signals.copying_failed.emit(path)
            continue

        # Emit corresponding signal
        signals.copying_finished.emit(path)
        result_paths.append(destname)
        logger.debug("Copied successfully")

    if offline_paths:
        signals.offline_paths.emit(offline_paths, False, True)
    if online_paths:
        signals.offline_paths.emit(online_paths, True, True)

    logger.debug("All paths copied")
    if callable(callback):
        callback(result_paths)
Ejemplo n.º 8
0
def offline_paths(paths, is_offline=True, is_recursive=True):
    """
    Makes given paths offline as is_offline flag
    @param paths paths [list]
    @param is_offline flag [bool]
    @return None
    """
    def process_error(error, error_info=''):
        msg = {
            INCORRECT_PATH:
            "Failed to change offline status '%s'. Incorrect path",
            NOT_IN_SYNC: "Path for changing offline status not in sync '%s'",
        }
        logger.error(msg[error], paths)
        if params.tracker:
            tracker_errors = {
                INCORRECT_PATH: params.tracker.INCORRECT_PATH,
                NOT_IN_SYNC: params.tracker.NOT_IN_SYNC,
            }
            params.tracker.share_error(0, tracker_errors[error],
                                       time.time() - start_time)

    start_time = time.time()

    timeout = 10 * 60  # seconds
    message_timeout = 2  # seconds

    step = 0
    command_str = tr("add to offline") if is_offline \
        else tr("remove from offline")

    for path in paths:
        path = ensure_unicode(path)
        try:
            # Name of the file relative to the root directory
            root, rel_path = get_relpath(path)
            if not rel_path:
                raise SharePathException()
        except SharePathException:
            process_error(INCORRECT_PATH)
            return

        if rel_path.endswith(FILE_LINK_SUFFIX):
            rel_path = rel_path[:-len(FILE_LINK_SUFFIX)]
            if not rel_path:
                process_error(INCORRECT_PATH)
                return

        logger.info("Offline on=%s, path '%s'...", is_offline, rel_path)
        while True:
            # Wait if file not in db yet
            try:
                if op.isfile(path):
                    uuid = params.sync.get_file_uuid(rel_path)
                elif op.isdir(path):
                    uuid = params.sync.get_folder_uuid(rel_path)
                else:
                    process_error(INCORRECT_PATH)
                    return

            except (FileNotFound, FileInProcessing, FileEventsDBError):
                uuid = None

            if uuid or (time.time() - start_time > timeout and node_synced):
                break

            if step == message_timeout:
                filename = op.basename(path)
                Application.show_tray_notification(
                    tr("Prepare {}.\n"
                       "Action will be completed after {} synced").format(
                           command_str, filename))
            step += 1
            time.sleep(1)

        if not uuid:
            process_error(NOT_IN_SYNC)
            Application.show_tray_notification(
                tr("Can't {}.\n"
                   "{} not in sync").format(command_str, path))
            return

        try:
            params.sync.file_added_to_indexing.emit(FilePath(path))
            success = params.sync.make_offline(uuid,
                                               is_offline,
                                               is_recursive=is_recursive)
        except FileEventsDBError:
            success = False
        if not success:
            params.sync.file_removed_from_indexing.emit(FilePath(path))
            Application.show_tray_notification(
                tr("Can't {} for path: {}.").format(command_str, path))
Ejemplo n.º 9
0
def collaboration_path_settings(paths):
    """
    Prepares opening of collaboration settings dialog for given paths

    @param paths Path (1 element list) to folder with (potential)
        collaboration [list]
    @return None
    """
    def process_error(error, error_info=''):
        msg = {
            INCORRECT_PATH:
                "Failed to open collaboration settings '%s'. Incorrect path",
            NOT_IN_SYNC:
                "Path for collaboration settings not in sync '%s'",
        }
        logger.error(msg[error], paths)
        if params.tracker:
            tracker_errors = {
                INCORRECT_PATH: params.tracker.INCORRECT_PATH,
                NOT_IN_SYNC: params.tracker.NOT_IN_SYNC,
            }
            params.tracker.share_error(
                0,
                tracker_errors[error],
                time.time() - start_time)

    start_time = time.time()

    timeout = 10 * 60  # seconds
    message_timeout = 2  # seconds

    step = 0
    if len(paths) != 1:
        process_error(INCORRECT_PATH)
        return

    path = ensure_unicode(paths[0])
    if not op.isdir(path):
        process_error(INCORRECT_PATH)
        return

    try:
        # Name of the file relative to the root directory
        root, rel_path = get_relpath(path)
        if not rel_path or '/' in rel_path:
            raise SharePathException()
    except SharePathException:
        process_error(INCORRECT_PATH)
        return

    logger.info("Collaboration settings path '%s'...", rel_path)

    while True:
        # Wait if file not in db yet
        try:
            uuid = params.sync.get_folder_uuid(rel_path)
        except (FileNotFound, FileInProcessing, FileEventsDBError):
            uuid = None

        if uuid or (time.time() - start_time > timeout and node_synced):
            break

        if step == message_timeout:
            filename = op.basename(path)
            Application.show_tray_notification(
                tr("Prepare open collaboration settings.\n"
                   "Dialog will be opened after {} synced").format(
                    filename))
        step += 1
        time.sleep(1)

    if not uuid:
        process_error(NOT_IN_SYNC)
        Application.show_tray_notification(
            tr("Can't open collaboration settings.\n"
               "{} not in sync").format(path))
        return

    logger.debug("Collaboration settings requested for path %s, uuid %s",
                 rel_path, uuid)
    signals.show_collaboration_settings.emit(rel_path, uuid)