Пример #1
0
    def display(self):
        if len(self.folderRefernece) == 0:

            print(FC.w("当前还没有正在备份的文件夹", 'g') + "\n")
        else:
            print(FC.w("当前备份文件夹信息:", 'c') + "\n")
            for idx, ref in enumerate(self.folderRefernece):
                print(
                    FC.g("[{}] {}\n".format(str(idx).zfill(2), ref['name'])) +
                    "     Src: {}".format(ref['src']))
                for destIdx, dest in enumerate(ref['dest']):
                    if dest['lastSyncTime'] is None:
                        print('       {} Dest: {}{}'.format(
                            FC.g("[{}]".format(str(destIdx).zfill(2))),
                            dest['destPath'], FC.y("[尚未备份]")))
                    else:
                        print('       {} Dest: {}{}'.format(
                            FC.g("[{}]".format(str(destIdx).zfill(2))),
                            dest['destPath'],
                            FC.y("[{}]".format(dest['lastSyncTime']))))

                    for remote in dest['remote']:
                        text = remote['username'] + '@' + remote[
                            'host'] + ':' + remote['rootPath']
                        print('            Remote: {}'.format(text))
                    print()
Пример #2
0
    def _syncFile(self, srcFile, destFile, destRootPath, remote, trashbin):
        """比较并同步单个文件"""
        # 大小不同直接复制
        if os.stat(srcFile).st_size != os.stat(destFile).st_size:
            print(FC.r("[Diff] ") + srcFile.split('/')[-1])
            trashbin.moveToTrashbin(destFile, destRootPath)
            shutil.copy(srcFile, destFile)
            for r in remote:
                r.put(srcFile, destFile[len(destRootPath) + 1:])
            return

        with open(srcFile, 'rb') as f1, open(destFile, 'rb') as f2:
            while True:
                data1 = f1.read(4096)
                data2 = f2.read(4096)
                if data1 != data2:
                    trashbin.moveToTrashbin(destFile, destRootPath)
                    shutil.copy(srcFile, destFile)
                    for r in remote:
                        r.put(srcFile, destFile[len(destRootPath) + 1:])
                    print(FC.r("[Diff] ") + srcFile.split('/')[-1])
                    return
                elif data1 == b'':
                    print(FC.g("[Same] ") + srcFile.split('/')[-1])
                    return
Пример #3
0
    def execAttachCommand(config):
        remoteLogFile = "/tmp/" + '_'.join(config['rootPath'].split('/'))
        fp = open(remoteLogFile, 'w')
        fp.write(json.dumps(config['transLog']))
        fp.close()

        remote = ServerTransporter(config)
        remote.put(remoteLogFile, remoteLogFile)
        if remote.attachCommand is not None:
            print(FC.g("[Do] ") + remote.username + '@' + remote.host + ':' + remote.rootPath + ' => ' + remote.attachCommand)
            stdin, stdout, stderr = remote._ssh.exec_command(remote.attachCommand)
            # 阻塞等待
            err = stderr.read()
Пример #4
0
    def _desktopNotify(self, syncedPaths, failedConnectPath):
        title = "备份完成,同步了{}个文件夹".format(len(syncedPaths))
        syncedText = '\n'.join(syncedPaths) + '\n'
        failedConnectText = ''

        for destPath, remotePath in failedConnectRemoteDict.items():
            failedConnectText += remotePath + '\n'

        text = syncedText + ('\n备份失败,remote未连接:\n' if failedConnectText != ''
                             else '') + failedConnectText
        os.system('notify-cron -t 5000 "{}" "{}"'.format(title, text))

        print(FC.g(title) + '\n' + text)
        with open(self.syncHistoryPath, 'a') as f:
            f.write("[{}]\n{}-------------------------------\n".format(
                getStrfTime(self.dateTimePattern), text))
Пример #5
0
    def _checkAndDeleteFormerPath(self, path):
        """删除修改前(被弃用)的文件夹路径"""
        if not os.path.isdir(path):
            return
        while True:

            print(("是否删除被弃置的文件夹[" + FC.g("{}") + "]?[y/N]").format(path))
            check = input().strip()

            if check == '' or check.upper() == 'N':
                return
            elif check.upper() == 'Y':
                shutil.rmtree(path)

                print(FC.r("文件夹已删除"))
                return
Пример #6
0
    def createAndTest():
        config = {}
        config['host'] = input("域名:")
        config['port'] = int(input("端口:"))
        config['username'] = input("用户名:")
        config['pwd'] = input("密码(留空则用秘钥文件登陆):").strip()
        if config['pwd'] == '':
            config['pwd'] = None
            config['privateKeyPath'] = input("请输入秘钥文件路径:")
        else:
            config['privateKeyPath'] = None
        config['rootPath'] = input("远端备份路径:")

        try:
            server = ServerTransporter(config)
            print(FC.g("测试连接成功"))
            while not server.mkdir(''):
                config['rootPath'] = input("请重新输入远程路径:")
            return config
        except:
            return False
Пример #7
0
    def modifyRenference(self):
        self.display()

        idx = input(FC.r("请输入要修改的序号:"))
        try:
            _idx = int(idx)
            assert _idx < len(self.folderRefernece), '序号超出范围'

            print("\n" + FC.g("[1]") + "修改原路径")
            print(FC.g("[2]") + "修改目标路径")
            modifyField = int(input(FC.c("请输入修改项:")))

            # modifyField = int(input())
            if modifyField == 1:
                # 修改原路径
                print("请输入备份原文件夹路径:")
                srcPath = input()

                while not os.path.isdir(srcPath):
                    print("\n该地址不是有效的文件夹,请输入备份源文件夹路径:")
                    srcPath = input()

                if srcPath == self.folderRefernece[_idx]['src']:
                    print("文件夹未变动")

                assert self._checkSameInReference(srcPath,
                                                  'src') < 0, "路径已存在在当前备份中"
                assert self._checkSameInReference(
                    srcPath, 'dest') < 0, "还不支持映射中存在相同的原路径和目标路径"

                self._checkAndDeleteFormerPath(
                    self.folderRefernece[_idx]['src'])
                self.folderRefernece[_idx]['src'] = srcPath
                self._updateFolderReference()
                print("更新完毕")
            else:

                for idx, dest in enumerate(self.folderRefernece[_idx]['dest']):
                    print("\n" + FC.g("[{}]".format(idx)) + dest['destPath'])
                    for remote in dest['remote']:
                        print("     " + remote['username'] + '@' +
                              remote['host'] + ':' + remote['rootPath'])

                _destIdx = int(input("请输入要修改的目标路径编号:"))
                assert 0 <= _destIdx <= idx, "编号有误"

                idx = 0
                dest = self.folderRefernece[_idx]['dest'][_destIdx]
                print("\n" + FC.g("[{}]".format(idx)) + dest['destPath'])
                for remote in dest['remote']:
                    idx += 1
                    print(
                        FC.g("[{}]".format(idx)) + remote['username'] + '@' +
                        remote['host'] + ':' + remote['rootPath'])

                _destIdx = int(input("请输入要修改的目标路径编号:"))
                assert 0 <= _destIdx <= idx, "编号有误"

                if _destIdx == 0:
                    # 修改目标路径
                    _t = True
                    while _t:
                        print("\n请输入备份目标文件夹绝对路径:")
                        destPath = input()
                        if not os.path.isdir(destPath):
                            os.makedirs(destPath)
                            _t = False
                        else:
                            _i = input("该文件夹非空,使用则清空文件夹,确认使用吗?[y/N]")
                            if _i.strip() == '' or _i.strip().upper() == 'N':
                                continue
                            elif _i.upper() == 'Y':
                                _t = False
                            else:
                                print("输入有误")

                    if destPath != dest['destPath']:
                        assert self._checkSameInReference(
                            destPath, 'dest') < 0, "路径已存在在当前备份中"
                        assert self._checkSameInReference(
                            destPath, 'src') < 0, "还不支持映射中存在相同的原路径和目标路径"

                        trashPath = TrashManager.getDestRootPathInTrash(
                            self.trashPath, dest['destPath'])
                        self._checkAndDeleteFormerPath(dest['destPath'])
                        self._checkAndDeleteFormerPath(trashPath)
                        dest['destPath'] = destPath
                        self._updateFolderReference()
                        print("更新完毕")
                    else:
                        print("文件夹未变动")
                        return
                else:
                    # remote
                    print("修改远程配置尚未完成")

        except AssertionError as e:
            print(e)
        except:
            print('序号不合规范')
Пример #8
0
    def addNewReference(self):
        print("请输入备份源文件夹路径:")
        srcPath = input()
        while not os.path.isdir(srcPath):
            print("\n该地址不是有效的文件夹,请输入备份源文件夹路径:")
            srcPath = input()

        # 若源文件夹已被关联, 则直接并入
        idx = self._checkSameInReference(srcPath, 'src')
        if idx >= 0:
            print("该文件夹已被映射, 只添加目标文件夹配置")

        destrefs = []
        while True:
            print(("\n请输入备份目标文件夹根路径\n(留空则用默认路径)[" + FC.y("{}") + "]:").format(
                self.defaultDestPath))
            destPath = input()
            if destPath.strip() == '':
                destPath = self.defaultDestPath
            if not os.path.isdir(destPath):
                os.makedirs(destPath)

            srcFolderName = os.path.realpath(srcPath).split('/')[-1]
            print(("\n请输入备份目标文件夹名\n(留空则用源文件夹名)[" + FC.y("{}") +
                   "]:").format(srcFolderName))
            destFolderName = input()
            if destFolderName.strip() == '':
                destFolderName = srcFolderName

            while os.path.isdir(os.path.join(destPath, destFolderName)):
                print("\n目标文件夹下已有同名文件夹,换个名字:")
                destFolderName = input()

            destPath = os.path.join(destPath, destFolderName)

            remotes = []
            ipt = input("是否要挂载远端文件夹(和备份文件夹相同修改,但不做检查)?[y/N]").strip().upper()
            while True:
                if ipt == 'Y':
                    remote = ServerTransporter.createAndTest()
                    if remote is not False:
                        remotes.append(remote)
                    else:
                        print("测试连接失败")
                    ipt = input("是否继续或重新添加远程地址?[y/N]").strip().upper()
                else:
                    break

            while True:
                try:
                    expiredPeriod = input(("\n请输入回收站清理过期天数, 留空则默认[" +
                                           FC.y("7天") + "]:")).strip()
                    if expiredPeriod == '':
                        expiredPeriod = 7
                        break
                    else:
                        expiredPeriod = int(expiredPeriod)
                        break
                except:
                    continue

            os.makedirs(destPath)
            destrefs.append({
                "destPath": destPath,
                "expiredPeriod": expiredPeriod * 24 * 3600,
                "lastSyncTime": None,
                "remote": remotes
            })

            i = input("是否继续添加目标地址?[y/N]").strip().upper()
            if i != 'Y':
                break

        if idx < 0:
            refname = input("再给这个备份关联起个名字, 留空默认[" + FC.y(srcFolderName) +
                            "]:").strip()
            if refname == '':
                refname = srcFolderName
            while self._checkSameInReference(refname, "name") >= 0:
                refname = input("名字已被占用重新输入, 留空默认[" + FC.y(srcFolderName) +
                                "]:").strip()
                if refname == '':
                    refname = srcFolderName

            reference = {"name": refname, "src": srcPath, "dest": destrefs}
            self.folderRefernece.append(reference)
        else:
            self.folderRefernece[idx]['dest'].extend(destrefs)
            reference = self.folderRefernece[idx]

        print(FC.g("添加成功"))
        self.showReference(reference)
        self._updateFolderReference()