Skip to content

Instantly share code, notes, and snippets.

@ly0
Created February 8, 2014 17:27
Show Gist options
  • Save ly0/8887143 to your computer and use it in GitHub Desktop.
Save ly0/8887143 to your computer and use it in GitHub Desktop.
百度网盘同步
#coding=utf-8
import os
import json
import sys
import re
from baidupcsapi import PCS
import progressbar
CWD = os.getcwd()
DIR_INFO = {}
REMOTE_ROOT = '/'
pcs = PCS('username','password')
class ProgressBar():
def __init__(self,filename):
self.filename = filename
self.first_call = True
def __call__(self, *args, **kwargs):
if self.first_call:
self.widgets = [progressbar.Percentage(), ' ', progressbar.Bar(marker=progressbar.RotatingMarker('>')),
' ', progressbar.FileTransferSpeed()]
self.pbar = progressbar.ProgressBar(widgets=self.widgets, maxval=kwargs['size']).start()
self.first_call = False
print 'Uploading',self.filename
if kwargs['size'] <= kwargs['progress']:
self.pbar.finish()
else:
self.pbar.update(kwargs['progress'])
def update_dir_info(dir):
global DIR_INFO
global pcs
try:
ret = pcs.list_files(dir).content
DIR_INFO[dir] = json.loads(ret)['list']
return True
except:
return False
def get_file_info(dir,filename):
global DIR_INFO
try:
for file in DIR_INFO[dir]:
if file['server_filename'] == filename:
return file
return True
except:
return False
def get_dir_files(dir):
global DIR_INFO
global pcs
try:
return DIR_INFO[dir]
except:
update_dir_info(dir)
return DIR_INFO[dir]
def need_upload(dir,local_path):
global DIR_INFO
filename = os.path.basename(local_path)
for file in get_dir_files(dir):
if file['isdir'] != 0:
continue
server_filename = filename_s2l(file['server_filename'])
server_filemtime = get_serverfile_localmtime(file['server_filename'])
local_filemtime = str(int(os.path.getmtime(local_path)))
if server_filename == filename and \
server_filemtime == local_filemtime:
# no need to upload
return ('same',file)
elif server_filename == filename and \
server_filemtime > local_filemtime:
# download
return ('download',file)
elif server_filename == filename and \
server_filemtime < local_filemtime:
# download
return ('upload',file)
return ('upload',None)
def get_serverfile_localmtime(filename):
foo = re.findall('.*?\[LMTIME(\d+)\]',filename)[0]
return foo
def filename_l2s(filename):
foo = filename
if foo.startswith('.'):
foo = '[#DOT#]' + foo[1:]
foo = foo.replace('/','[#SLASH#]')
return foo
def filename_s2l(filename):
try:
foo = filename
foo = foo.replace('[#DOT#]','.').replace('[#SLASH#]','/')
foo = re.findall('(.*?)\[LMTIME\d+\]',foo)[0]
except:
return filename
return foo
def format_local_filename(file_path):
filename = os.path.basename(file_path)
local_mtime = int(os.path.getmtime(file_path))
foo = '%s[LMTIME%s]' % (filename, local_mtime)
return filename_l2s(foo)
for dir_name,sub_dir,files in os.walk(CWD):
remote_dir = dir_name.replace(CWD,'')
if not remote_dir.startswith('/'):
remote_dir = '/' + remote_dir
remote_list = get_dir_files(dir_name)
for f in files:
# skip file with name ending with ~
if f.endswith('~'):
continue
local_path = '%s/%s' % (dir_name, f)
opt = need_upload(remote_dir,local_path)
if opt[0] == 'upload':
if opt[1]:
ret = pcs.delete([opt[1]['path']])
handler = open(local_path,'rb')
print 'uploading',remote_dir,filename_l2s(f),local_path,os.path.getmtime(local_path)
ret = pcs.upload(remote_dir, handler, filename=format_local_filename(local_path),ondup='overwrite')
elif opt[0] == 'same':
pass
else:
# download
server_file = opt[1]
# server is newer than local -> download
print 'Downloading',filename_s2l(server_file['server_filename'])
with open(local_path,'wb') as down:
down.write(pcs.download(server_file['path']).content)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment