经常有一些文档需要在公司和家里的两地电脑间手工同步,很麻烦,于是利用七牛云免费的空间来做服务端实现同步功能。
同时,为了文档内容保密,我采用cryptography模块(通过指定一个复杂的字符串)对文件加密,这样即使别人获取了七牛云上的文件也无法破解。
import os, time, uuid, requests
from qiniu import Auth, put_file, urlsafe_base64_encode, BucketManager
import qiniu.config
from cryptography.fernet import Fernet
from binascii import b2a_hex, a2b_hex
class Sync(object):
def __init__(self, userKey):
self.fernet = Fernet(b'dUTMoQzCwiamBkwNTGR4AXrw-xxxxxxx=')
self.qn = Auth('UhzOHyzt0MeL', 'GzTlY7c30WZw')
self.userKey = userKey
self.buckName = 'bsync'
self.tmpFile = os.path.join(os.environ['TEMP'], self.userKey)
self.bmFile = os.environ['LOCALAPPDATA'] + '\\User Data\\'
def getRLUT(self):
'''get remote last update time'''
bucket = BucketManager(self.qn)
ret, obj, info = bucket.list(bucket=self.buckName, prefix=self.userKey+'/')
lastUpdateTime = ''
for i in ret['items']:
updateTime = i['key'].split('/')[1]
if updateTime > lastUpdateTime:
lastUpdateTime = updateTime
return lastUpdateTime
def put(self, timeStr):
with open(self.bmFile, 'r', encoding='utf8') as f:
content = self.fernet.encrypt(bytes(f.read(), encoding='utf8'))
with open(self.tmpFile, 'wb') as f:
f.write(content)
fileKey = self.genFileKey(timeStr)
token = self.qn.upload_token(self.buckName, fileKey, 3600)
ret, info = put_file(token, fileKey, self.tmpFile)
def get(self, timeStr):
fileKey = self.genFileKey(timeStr)
base_url = 'http://xxxxx.bkt.clouddn.com/%s' % (fileKey)
private_url = self.qn.private_download_url(base_url, expires=3600)
resp = requests.get(private_url)
with open(self.bmFile, 'w', encoding='utf8') as f:
content = self.fernet.decrypt(resp.content)
f.write(content.decode('utf8'))
def genFileKey(self, timeStr):
return self.userKey + '/' + timeStr
def run(self):
if not os.path.exists(self.bmFile):
return
remoteLastTimeStr = self.getRLUT()
localLastTimeStr = time.strftime('%Y%m%d%H%M%S', time.localtime(os.path.getmtime(self.bmFile)))
if remoteLastTimeStr < localLastTimeStr:
self.put(localLastTimeStr)
print("服务器已更新为最新")
elif remoteLastTimeStr > localLastTimeStr:
self.get(remoteLastTimeStr)
print("本地已更新为最新")
else:
print("服务器与本地状态同步")
if __name__ == '__main__':
sb = Sync('test')
sb.run()