Esempio n. 1
0
def mega(folder_name):
    mega_ = Mega()
    mega_.login(email=os.environ['EMAIL'], password=os.environ['PASS'])
    created_nodes = mega_.create_folder(folder_name)
    yield mega_
    node_id = next(iter(created_nodes.values()))
    mega_.destroy(node_id)
Esempio n. 2
0
class MegaBackend(duplicity.backend.Backend):
    """Connect to remote store using Mega.co.nz API"""

    def __init__(self, parsed_url):
        duplicity.backend.Backend.__init__(self, parsed_url)

        try:
            from mega import Mega
        except ImportError:
            raise BackendException('Mega.co.nz backend requires Mega.co.nz APIs Python Module'
                                   '(see https://github.com/richardasaurus/mega.py).')

        # Setup client instance.
        self.client = Mega()
        self.client.domain = parsed_url.hostname
        self.__authorize(parsed_url.username, self.get_password())

        # Fetch destination folder entry (and crete hierarchy if required).
        folder_names = parsed_url.path[1:].split('/')
        files = self.client.get_files()

        parent_folder = self.client.root_id
        for folder_name in folder_names:
            entries = self.__filter_entries(files, parent_folder, folder_name, 'folder')
            if len(entries):
                # use first matching folder as new parent
                parent_folder = entries.keys()[0]
            else:
                # create subfolder if folder doesn't exist and use its handle as parent
                folder_node = self.client.create_folder(folder_name, parent_folder)
                parent_folder = self.client.get_id_from_obj(folder_node)
                # update filelist after creating new folder
                files = self.client.get_files()

        self.folder = parent_folder

    @retry
    def put(self, source_path, remote_filename=None, raise_errors=False):
        """Transfer source_path to remote_filename"""
        # Default remote file name.
        if not remote_filename:
            remote_filename = source_path.get_filename()

        try:
            # If remote file already exists in destination folder, remove it.
            files = self.client.get_files()
            entries = self.__filter_entries(files, self.folder, remote_filename, 'file')

            for entry in entries:
                self.client.delete(entry)

            self.client.upload(source_path.get_canonical(), self.folder, dest_filename=remote_filename)

        except Exception, e:
            self.__handle_error("Failed to upload file '%s' to remote folder '%s': %s"
                                % (source_path.get_canonical(), self.__get_node_name(self.folder), str(e)), raise_errors)
Esempio n. 3
0
class MegaBackend(duplicity.backend.Backend):
    """Connect to remote store using Mega.co.nz API"""
    def __init__(self, parsed_url):
        duplicity.backend.Backend.__init__(self, parsed_url)

        try:
            from mega import Mega
        except ImportError:
            raise BackendException(
                'Mega.co.nz backend requires Mega.co.nz APIs Python Module'
                '(see https://github.com/richardasaurus/mega.py).')

        # Setup client instance.
        self.client = Mega()
        self.client.domain = parsed_url.hostname
        self.__authorize(parsed_url.username, self.get_password())

        # Fetch destination folder entry (and crete hierarchy if required).
        folder_names = parsed_url.path[1:].split('/')
        files = self.client.get_files()

        parent_folder = self.client.root_id
        for folder_name in folder_names:
            entries = self.__filter_entries(files, parent_folder, folder_name,
                                            'folder')
            if len(entries):
                # use first matching folder as new parent
                parent_folder = entries.keys()[0]
            else:
                # create subfolder if folder doesn't exist and use its handle as parent
                folder_node = self.client.create_folder(
                    folder_name, parent_folder)
                parent_folder = self.client.get_id_from_obj(folder_node)
                # update filelist after creating new folder
                files = self.client.get_files()

        self.folder = parent_folder

    @retry
    def put(self, source_path, remote_filename=None, raise_errors=False):
        """Transfer source_path to remote_filename"""
        # Default remote file name.
        if not remote_filename:
            remote_filename = source_path.get_filename()

        try:
            # If remote file already exists in destination folder, remove it.
            files = self.client.get_files()
            entries = self.__filter_entries(files, self.folder,
                                            remote_filename, 'file')

            for entry in entries:
                self.client.delete(entry)

            self.client.upload(source_path.get_canonical(),
                               self.folder,
                               dest_filename=remote_filename)

        except Exception, e:
            self.__handle_error(
                "Failed to upload file '%s' to remote folder '%s': %s" %
                (source_path.get_canonical(), self.__get_node_name(
                    self.folder), str(e)), raise_errors)
Esempio n. 4
0
class MegaBackend(duplicity.backend.Backend):
    """Connect to remote store using Mega.co.nz API"""

    def __init__(self, parsed_url):
        duplicity.backend.Backend.__init__(self, parsed_url)

        try:
            from mega import Mega
        except ImportError:
            raise BackendException('Mega.co.nz backend requires Mega.co.nz APIs Python Module'
                                   '(see https://github.com/richardasaurus/mega.py).')

        # Setup client instance.
        self.client = Mega()
        self.client.domain = parsed_url.hostname
        self.__authorize(parsed_url.username, self.get_password())

        # Fetch destination folder entry (and crete hierarchy if required).
        folder_names = parsed_url.path[1:].split('/')
        files = self.client.get_files()

        parent_folder = self.client.root_id
        for folder_name in folder_names:
            entries = self.__filter_entries(files, parent_folder, folder_name, 'folder')
            if len(entries):
                # use first matching folder as new parent
                parent_folder = entries.keys()[0]
            else:
                # create subfolder if folder doesn't exist and use its handle as parent
                folder_node = self.client.create_folder(folder_name, parent_folder)
                parent_folder = self.client.get_id_from_obj(folder_node)
                # update filelist after creating new folder
                files = self.client.get_files()

        self.folder = parent_folder

    def _put(self, source_path, remote_filename):
        try:
            self._delete(remote_filename)
        except Exception:
            pass
        self.client.upload(source_path.get_canonical(), self.folder, dest_filename=remote_filename)

    def _get(self, remote_filename, local_path):
        files = self.client.get_files()
        entries = self.__filter_entries(files, self.folder, remote_filename, 'file')
        if len(entries):
            # get first matching remote file
            entry = entries.keys()[0]
            self.client.download((entry, entries[entry]), dest_filename=local_path.name)
        else:
            raise BackendException("Failed to find file '%s' in remote folder '%s'"
                                   % (remote_filename, self.__get_node_name(self.folder)),
                                   code=log.ErrorCode.backend_not_found)

    def _list(self):
        entries = self.client.get_files_in_node(self.folder)
        return [self.client.get_name_from_file({entry: entries[entry]}) for entry in entries]

    def _delete(self, filename):
        files = self.client.get_files()
        entries = self.__filter_entries(files, self.folder, filename, 'file')
        if len(entries):
            self.client.destroy(entries.keys()[0])
        else:
            raise BackendException("Failed to find file '%s' in remote folder '%s'"
                                   % (filename, self.__get_node_name(self.folder)),
                                   code=log.ErrorCode.backend_not_found)

    def __get_node_name(self, handle):
        """get node name from public handle"""
        files = self.client.get_files()
        return self.client.get_name_from_file({handle: files[handle]})

    def __authorize(self, email, password):
        self.client.login(email, password)

    def __filter_entries(self, entries, parent_id=None, title=None, type=None):
        result = {}
        type_map = {'folder': 1, 'file': 0}

        for k, v in entries.items():
            try:
                if parent_id is not None:
                    assert(v['p'] == parent_id)
                if title is not None:
                    assert(v['a']['n'] == title)
                if type is not None:
                    assert(v['t'] == type_map[type])
            except AssertionError:
                continue

            result.update({k: v})

        return result
Esempio n. 5
0
class MegaBackend(duplicity.backend.Backend):
    """Connect to remote store using Mega.co.nz API"""
    def __init__(self, parsed_url):
        duplicity.backend.Backend.__init__(self, parsed_url)

        try:
            from mega import Mega
        except ImportError:
            raise BackendException(
                'Mega.co.nz backend requires Mega.co.nz APIs Python Module'
                '(see https://github.com/richardasaurus/mega.py).')

        # Setup client instance.
        self.client = Mega()
        self.client.domain = parsed_url.hostname
        self.__authorize(parsed_url.username, self.get_password())

        # Fetch destination folder entry (and crete hierarchy if required).
        folder_names = parsed_url.path[1:].split('/')
        files = self.client.get_files()

        parent_folder = self.client.root_id
        for folder_name in folder_names:
            entries = self.__filter_entries(files, parent_folder, folder_name,
                                            'folder')
            if len(entries):
                # use first matching folder as new parent
                parent_folder = entries.keys()[0]
            else:
                # create subfolder if folder doesn't exist and use its handle as parent
                folder_node = self.client.create_folder(
                    folder_name, parent_folder)
                parent_folder = self.client.get_id_from_obj(folder_node)
                # update filelist after creating new folder
                files = self.client.get_files()

        self.folder = parent_folder

    def _put(self, source_path, remote_filename):
        try:
            self._delete(remote_filename)
        except Exception:
            pass
        self.client.upload(source_path.get_canonical(),
                           self.folder,
                           dest_filename=remote_filename)

    def _get(self, remote_filename, local_path):
        files = self.client.get_files()
        entries = self.__filter_entries(files, self.folder, remote_filename,
                                        'file')
        if len(entries):
            # get first matching remote file
            entry = entries.keys()[0]
            self.client.download((entry, entries[entry]),
                                 dest_filename=local_path.name)
        else:
            raise BackendException(
                "Failed to find file '%s' in remote folder '%s'" %
                (remote_filename, self.__get_node_name(self.folder)),
                code=log.ErrorCode.backend_not_found)

    def _list(self):
        entries = self.client.get_files_in_node(self.folder)
        return [
            self.client.get_name_from_file({entry: entries[entry]})
            for entry in entries
        ]

    def _delete(self, filename):
        files = self.client.get_files()
        entries = self.__filter_entries(files, self.folder, filename, 'file')
        if len(entries):
            self.client.destroy(entries.keys()[0])
        else:
            raise BackendException(
                "Failed to find file '%s' in remote folder '%s'" %
                (filename, self.__get_node_name(self.folder)),
                code=log.ErrorCode.backend_not_found)

    def __get_node_name(self, handle):
        """get node name from public handle"""
        files = self.client.get_files()
        return self.client.get_name_from_file({handle: files[handle]})

    def __authorize(self, email, password):
        self.client.login(email, password)

    def __filter_entries(self, entries, parent_id=None, title=None, type=None):
        result = {}
        type_map = {'folder': 1, 'file': 0}

        for k, v in entries.items():
            try:
                if parent_id is not None:
                    assert (v['p'] == parent_id)
                if title is not None:
                    assert (v['a']['n'] == title)
                if type is not None:
                    assert (v['t'] == type_map[type])
            except AssertionError:
                continue

            result.update({k: v})

        return result