更新PyOne3.0!!支持绑定多个onedrive网盘

PyOne3.0
abbeyokgo 6 years ago
parent f722767811
commit 09fc68e228
  1. 0
      README.md
  2. 146
      admin.py
  3. 50
      config.py.sample
  4. 0
      data/README.md
  5. 247
      function.py
  6. 0
      requirements.txt
  7. 131
      run.py
  8. 122
      static/css/theme.css
  9. 0
      static/img/bg-bottom.svg
  10. 0
      static/js/hashmap.js
  11. 0
      static/js/webuploader.min.js
  12. 34
      supervisord.conf.sample
  13. 0
      templates/_macro.html
  14. 22
      templates/admin/cache.html
  15. 2
      templates/admin/edit.html
  16. 1
      templates/admin/install_0.html
  17. 7
      templates/admin/install_1.html
  18. 2
      templates/admin/layout.html
  19. 2
      templates/admin/login.html
  20. 61
      templates/admin/manage.html
  21. 0
      templates/admin/setpass.html
  22. 24
      templates/admin/setting.html
  23. 18
      templates/admin/upload.html
  24. 4
      templates/admin/upload_local.html
  25. 0
      templates/footer.html
  26. 0
      templates/head.html
  27. 32
      templates/header.html
  28. 12
      templates/index.html
  29. 0
      templates/layout.html
  30. 0
      templates/password.html
  31. 0
      templates/readme.html
  32. 0
      templates/show/any.html
  33. 0
      templates/show/audio.html
  34. 0
      templates/show/code.html
  35. 0
      templates/show/image.html
  36. 0
      templates/show/video.html
  37. 0
      templates/show/video2.html
  38. 0
      upload/README.md

@ -19,8 +19,8 @@ eventlet.monkey_patch()
admin = Blueprint('admin', __name__,url_prefix='/admin')
############功能函数
def set(key,value):
allow_key=['title','share_path','downloadUrl_timeout','allow_site','password','client_secret','client_id','tj_code']
def set(key,value,user='A'):
allow_key=['title','downloadUrl_timeout','allow_site','password','client_secret','client_id','share_path','other_name','tj_code']
if key not in allow_key:
return u'禁止修改'
print 'set {}:{}'.format(key,value)
@ -28,29 +28,24 @@ def set(key,value):
with open(config_path,'r') as f:
old_text=f.read()
with open(config_path,'w') as f:
if len(re.findall(key,old_text))>0:
if key=='allow_site':
value=value.split(',')
new_text=re.sub('{}=.*'.format(key),'{}={}'.format(key,value),old_text)
elif key=='tj_code':
new_text=re.sub('{}=.*'.format(key),'{}="""{}"""'.format(key,value),old_text)
else:
new_text=re.sub('{}=.*'.format(key),'{}="{}"'.format(key,value),old_text)
if key in ['client_secret','client_id','share_path','other_name']:
old_kv=re.findall('"{}":{{[\w\W]*?}}'.format(user),old_text)[0]
new_kv=re.sub('"{}":.*?,'.format(key),'"{}":"{}",'.format(key,value),old_kv)
new_text=old_text.replace(old_kv,new_kv)
elif key=='allow_site':
value=value.split(',')
new_text=re.sub('{}=.*'.format(key),'{}={}'.format(key,value),old_text)
elif key=='tj_code':
new_text=re.sub('{}=.*'.format(key),'{}="""{}"""'.format(key,value),old_text)
else:
if key=='allow_site':
value=value.split(',')
new_text=old_text+'\n\n{}={}'.format(key,value)
elif key=='tj_code':
new_text=re.sub('{}=.*'.format(key),'{}="""{}"""'.format(key,value),old_text)
else:
new_text=old_text+'\n\n{}="{}"'.format(key,value)
new_text=re.sub('{}=.*'.format(key),'{}="{}"'.format(key,value),old_text)
f.write(new_text)
############视图函数
@admin.before_request
def before_request():
if request.endpoint.startswith('admin') and request.endpoint!='admin.login' and request.endpoint!='admin.install' and session.get('login') is None:
if request.endpoint.startswith('admin') and request.endpoint!='admin.login' and session.get('login') is None: #and request.endpoint!='admin.install'
return redirect(url_for('admin.login'))
@ -65,13 +60,11 @@ def web_console():
if action in ['UploadDir','Upload']:
local=urllib.unquote(request.args.get('local'))
remote=urllib.unquote(request.args.get('remote'))
cmd=["python","-u",os.path.join(config_dir,'function.py'),action,local,remote]
user=urllib.unquote(request.args.get('user'))
cmd=["python","-u",os.path.join(config_dir,'function.py'),action,local,remote,user]
elif action=='UpdateFile':
dir_=request.args.get('dir')
if dir_=='/':
cmd=["python","-u",os.path.join(config_dir,'function.py'),action]
else:
cmd=["python","-u",os.path.join(config_dir,'function.py'),'Dir',dir_]
type_=request.args.get('type')
cmd=["python","-u",os.path.join(config_dir,'function.py'),'UpdateFile',type_]
else:
cmd=["python","-u",os.path.join(config_dir,'function.py'),action]
p = g.run(cmd)
@ -89,7 +82,6 @@ def web_console():
def setting():
if request.method=='POST':
title=request.form.get('title','PyOne')
share_path=request.form.get('share_path','/')
downloadUrl_timeout=request.form.get('downloadUrl_timeout',5*60)
allow_site=request.form.get('allow_site','no-referrer')
tj_code=request.form.get('tj_code','')
@ -104,10 +96,16 @@ def setting():
new_password=password1
set('title',title)
set('downloadUrl_timeout',downloadUrl_timeout)
set('share_path',share_path)
set('allow_site',allow_site)
set('tj_code',tj_code)
set('password',new_password)
####网盘信息处理
for k,v in request.form.to_dict().items():
if 'share_path' in k or 'other_name' in k:
user=re.findall('\[(.*?)\]',k)[0]
key=re.findall('(.*)\[',k)[0]
print('setting {}\'s {}\'s value {}'.format(user,key,v))
set(key,v,user)
reload()
return render_template('admin/setting.html')
return render_template('admin/setting.html')
@ -118,6 +116,7 @@ def setting():
@admin.route('/upload',methods=["POST","GET"])
def upload():
if request.method=='POST':
user=request.form.get('user').encode('utf-8')
local=request.form.get('local').encode('utf-8')
remote=request.form.get('remote').encode('utf-8')
if not os.path.exists(local):
@ -127,7 +126,7 @@ def upload():
action='Upload'
else:
action='UploadDir'
return render_template('admin/upload.html',remote=remote,local=local,action=action)
return render_template('admin/upload.html',remote=remote,local=local,action=action,user=user)
return render_template('admin/upload.html')
@ -135,8 +134,8 @@ def upload():
@admin.route('/cache',methods=["POST","GET"])
def cache():
if request.method=='POST':
dir_=request.form.get('dir')
return render_template('admin/cache.html',dir=dir_,action='UpdateFile')
type=request.form.get('type')
return render_template('admin/cache.html',type=type,action='UpdateFile')
return render_template('admin/cache.html')
@ -144,11 +143,10 @@ def cache():
def manage():
if request.method=='POST':
pass
path=urllib.unquote(request.args.get('path','/'))
if path=='':
path='/'
if path!='/' and path.startswith('/'):
path=re.sub('^/+','',path)
path=urllib.unquote(request.args.get('path','A:/'))
user,n_path=path.split(':')
if n_path=='':
path=':'.join([user,'/'])
page=request.args.get('page',1,type=int)
image_mode=request.args.get('image_mode')
sortby=request.args.get('sortby')
@ -165,7 +163,9 @@ def manage():
order=order
resp,total = FetchData(path=path,page=page,per_page=50,sortby=sortby,order=order)
pagination=Pagination(query=None,page=page, per_page=50, total=total, items=None)
resp=make_response(render_template('admin/manage.html',pagination=pagination,items=resp,path=path,sortby=sortby,order=order,endpoint='admin.manage'))
if path.split(':',1)[-1]=='/':
path=':'.join([path.split(':',1)[0],''])
resp=make_response(render_template('admin/manage.html',pagination=pagination,items=resp,path=path,sortby=sortby,order=order,cur_user=user,endpoint='admin.manage'))
resp.set_cookie('admin_sortby',str(sortby))
resp.set_cookie('admin_order',str(order))
return resp
@ -175,9 +175,10 @@ def manage():
def edit():
if request.method=='POST':
fileid=request.form.get('fileid')
user=request.form.get('user')
content=request.form.get('content').encode('utf-8')
info={}
token=GetToken()
token=GetToken(user=user)
app_url=GetAppUrl()
headers={'Authorization':'bearer {}'.format(token)}
url=app_url+'v1.0/me/drive/items/{}/content'.format(fileid)
@ -193,6 +194,9 @@ def edit():
path=file['path'].replace('/'+name,'').replace(name,'')
if path=='':
path='/'
if not path.startswith('/'):
path='/'+path
path='{}:{}'.format(user,path)
key='has_item$#$#$#$#{}$#$#$#$#{}'.format(path,name)
rd.delete(key)
else:
@ -204,19 +208,20 @@ def edit():
info['msg']='修改超时'
return jsonify(info)
fileid=request.args.get('fileid')
user=request.args.get('user')
name=GetName(fileid)
ext=name.split('.')[-1]
language=CodeType(ext)
if language is None:
language='Text'
content=_remote_content(fileid)
return render_template('admin/edit.html',content=content,fileid=fileid,name=name,language=language)
content=_remote_content(fileid,user)
return render_template('admin/edit.html',content=content,fileid=fileid,name=name,language=language,cur_user=user)
###本地上传文件只onedrive,通过服务器中转
@admin.route('/upload_local',methods=['POST','GET'])
def upload_local():
remote_folder=request.args.get('path')
return render_template('admin/upload_local.html',remote_folder=remote_folder)
user,remote_folder=request.args.get('path').split(':')
return render_template('admin/upload_local.html',remote_folder=remote_folder,cur_user=user)
@admin.route('/checkChunk', methods=['POST'])
def checkChunk():
@ -263,13 +268,14 @@ def recv_upload(): # 接收前端上传的一个分片
@admin.route('/to_one',methods=['GET'])
def server_to_one():
user=request.args.get('user')
filename=request.args.get('filename').encode('utf-8')
remote_folder=request.args.get('remote_folder').encode('utf-8')
if remote_folder!='/':
remote_folder=remote_folder+'/'
local_dir=os.path.join(config_dir,'upload')
filepath=urllib.unquote(os.path.join(local_dir,filename))
_upload_session=Upload_for_server(filepath,remote_folder)
_upload_session=Upload_for_server(filepath,remote_folder,user)
def read_status():
while 1:
try:
@ -290,13 +296,14 @@ def server_to_one():
def setFile(filename=None):
if request.method=='POST':
path=request.form.get('path')
user,n_path=path.split(':')
filename=request.form.get('filename')
if not path.startswith('/'):
path='/'+path
remote_file=os.path.join(path,filename)
if not n_path.startswith('/'):
n_path='/'+n_path
remote_file=os.path.join(n_path,filename)
content=request.form.get('content').encode('utf-8')
info={}
token=GetToken()
token=GetToken(user=user)
app_url=GetAppUrl()
headers={'Authorization':'bearer {}'.format(token)}
url=app_url+'v1.0/me/drive/items/root:{}:/content'.format(remote_file)
@ -304,11 +311,9 @@ def setFile(filename=None):
r=requests.put(url,headers=headers,data=content,timeout=10)
data=json.loads(r.content)
if data.get('id'):
AddResource(data)
AddResource(data,user)
info['status']=0
info['msg']='添加成功'
if path.startswith('/') and path!='/':
path=path[1:]
key='has_item$#$#$#$#{}$#$#$#$#{}'.format(path,filename)
rd.delete(key)
else:
@ -319,15 +324,17 @@ def setFile(filename=None):
info['msg']='超时'
return jsonify(info)
path=urllib.unquote(request.args.get('path'))
user,n_path=path.split(':')
_,fid,i=has_item(path,filename)
if fid!=False:
return redirect(url_for('admin.edit',fileid=fid))
return render_template('admin/setpass.html',path=path,filename=filename)
return redirect(url_for('admin.edit',fileid=fid,user=user))
return render_template('admin/setpass.html',path=path,filename=filename,cur_user=user)
@admin.route('/delete',methods=["POST"])
def delete():
ids=request.form.get('id')
user=request.form.get('user')
if ids is None:
return jsonify({'msg':u'请选择要删除的文件','status':0})
ids=ids.split('##')
@ -343,9 +350,14 @@ def delete():
path='/'
else:
path=items.find_one({'id':file['parent']})['path']
if not path.startswith('/'):
path='/'+path
path='{}:{}'.format(user,path)
key='has_item$#$#$#$#{}$#$#$#$#{}'.format(path,name)
rd.delete(key)
status=DeleteRemoteFile(id)
kc='{}:content'.format(id)
rd.delete(kc)
status=DeleteRemoteFile(id,user)
if status:
infos['delete']+=1
else:
@ -356,25 +368,27 @@ def delete():
@admin.route('/add_folder',methods=['POST'])
def AddFolder():
folder_name=request.form.get('folder_name')
grand_path=request.args.get('path')
path=request.args.get('path')
user,grand_path=path.split(':')
if grand_path=='' or grand_path is None:
grand_path='/'
else:
if grand_path.startswith('/'):
grand_path=grand_path[1:]
result=CreateFolder(folder_name,grand_path)
result=CreateFolder(folder_name,grand_path,user)
return jsonify({'result':result})
@admin.route('/move_file',methods=['POST'])
def MoveFileToNewFolder():
fileid=request.form.get('fileid')
user=request.form.get('user')
new_folder_path=request.form.get('new_folder_path')
if new_folder_path=='' or new_folder_path is None:
new_folder_path='/'
else:
if new_folder_path.startswith('/'):
new_folder_path=new_folder_path[1:]
result=MoveFile(fileid,new_folder_path)
result=MoveFile(fileid,new_folder_path,user)
return jsonify({'result':result})
@ -402,7 +416,7 @@ def logout():
def reload():
cmd='supervisorctl -c {} restart pyone'.format(os.path.join(config_dir,'supervisord.conf'))
subprocess.Popen(cmd,shell=True)
flash('正在重启网站...')
flash('正在重启网站...如果更改了分享目录,请更新缓存')
return redirect(url_for('admin.setting'))
@ -411,18 +425,17 @@ def reload():
###########################################安装
@admin.route('/install',methods=['POST','GET'])
def install():
if items.count()>0 or os.path.exists(os.path.join(config_dir,'data/token.json')):
return redirect('/')
if request.method=='POST':
step=request.form.get('step',type=int)
user=request.form.get('user')
if step==1:
client_secret=request.form.get('client_secret')
client_id=request.form.get('client_id')
redirect_uri='https://auth.3pp.me'
set('client_secret',client_secret)
set('client_id',client_id)
set('client_secret',client_secret,user)
set('client_id',client_id,user)
login_url=LoginUrl.format(client_id=client_id,redirect_uri=redirect_uri)
return render_template('admin/install_1.html',client_secret=client_secret,client_id=client_id,login_url=login_url)
return render_template('admin/install_1.html',client_secret=client_secret,client_id=client_id,login_url=login_url,cur_user=user)
else:
client_secret=request.form.get('client_secret')
client_id=request.form.get('client_id')
@ -435,18 +448,17 @@ def install():
r=requests.post(url,data=data,headers=headers)
Atoken=json.loads(r.text)
if Atoken.get('access_token'):
with open(os.path.join(config_dir,'data/Atoken.json'),'w') as f:
with open(os.path.join(config_dir,'data/{}_Atoken.json'.format(user)),'w') as f:
json.dump(Atoken,f,ensure_ascii=False)
app_url=GetAppUrl()
refresh_token=Atoken.get('refresh_token')
with open(os.path.join(config_dir,'data/AppUrl'),'w') as f:
f.write(app_url)
token=ReFreshToken(refresh_token)
with open(os.path.join(config_dir,'data/token.json'),'w') as f:
token=ReFreshToken(refresh_token,user)
with open(os.path.join(config_dir,'data/{}_token.json'.format(user)),'w') as f:
json.dump(token,f,ensure_ascii=False)
return make_response('<h1>授权成功!<a href="/">点击进入首页</a><br>请在后台另开一个ssh窗口,运行:<pre>python function.py UpdateFile</pre>进行更新数据操作</h1>')
else:
return jsonify(Atoken)
resp=render_template('admin/install_0.html',step=1)
step=request.args.get('step',type=int)
user=request.args.get('user','A')
resp=render_template('admin/install_0.html',step=step,cur_user=user)
return resp

@ -0,0 +1,50 @@
#-*- coding=utf-8 -*-
import os
#限制调用域名
allow_site=[u'no-referrer']
#######源码目录
config_dir="/home/centos/PyOne"
data_dir=os.path.join(config_dir,'data')
#下载链接过期时间
downloadUrl_timeout="300"
#后台密码设置
password="pyone210210"
#网站名称
title="资源整合"
tj_code="""<script src="https://s19.cnzz.com/z_stat.php?id=1274508765&web_id=1274508765" language="JavaScript"></script>"""
#onedrive api设置
redirect_uri='https://auth.3pp.me/' #不要修改!
BaseAuthUrl='https://login.microsoftonline.com'
app_url=u'https://graph.microsoft.com/'
od_users={
"A":{
"client_id":"d7d69676-b925-4714-a9bd-2200e3972179",
"client_secret":"cpmRN8154|-jfmmNMMVI3*:",
"share_path":"/日剧",
"other_name":"日日香",
"order":1
},
"B":{
"client_id":"32489f67-d11d-4dc9-9352-ed7e95916d6c",
"client_secret":"sakUNW#iiyxQLDM01186={=",
"share_path":"/",
"other_name":"网盘2区",
"order":2
},
"C":{
"client_id":"",
"client_secret":"",
"share_path":"/",
"other_name":"网盘3区",
"order":3
}
}

@ -24,7 +24,7 @@ from config import *
from pymongo import MongoClient,ASCENDING,DESCENDING
######mongodb
client = MongoClient('localhost',27017)
db=client.two
db=client.three
items=db.items
rd=Redis(host='localhost',port=6379)
@ -40,13 +40,15 @@ headers={'User-Agent':'ISV|PyOne|PyOne/2.0'}
def convert2unicode(string):
return string.encode('utf-8')
def get_value(key):
def get_value(key,user='A'):
allow_key=['client_secret','client_id']
if key not in allow_key:
return u'禁止获取'
config_path=os.path.join(config_dir,'config.py')
with open(config_path,'r') as f:
value=re.findall('{}="(.*)"'.format(key),f.read())[0]
text=f.read()
kv=re.findall('"{}":{{[\w\W]*?}}'.format(user),text)[0]
value=re.findall('"{}":"(.*?)"'.format(key),kv)[0]
return value
def GetName(id):
@ -86,9 +88,9 @@ def open_json(filepath):
return token
return token
def ReFreshToken(refresh_token):
client_id=get_value('client_id')
client_secret=get_value('client_secret')
def ReFreshToken(refresh_token,user='A'):
client_id=get_value('client_id',user)
client_secret=get_value('client_secret',user)
headers['Content-Type']='application/x-www-form-urlencoded'
data=ReFreshData.format(client_id=client_id,redirect_uri=urllib.quote(redirect_uri),client_secret=client_secret,refresh_token=refresh_token)
url=OAuthUrl
@ -96,22 +98,23 @@ def ReFreshToken(refresh_token):
return json.loads(r.text)
def GetToken(Token_file='token.json'):
def GetToken(Token_file='token.json',user='A'):
Token_file='{}_{}'.format(user,Token_file)
if os.path.exists(os.path.join(data_dir,Token_file)):
token=open_json(os.path.join(data_dir,Token_file))
try:
if time.time()>int(token.get('expires_on')):
print 'token timeout'
refresh_token=token.get('refresh_token')
token=ReFreshToken(refresh_token)
token=ReFreshToken(refresh_token,user)
if token.get('access_token'):
with open(os.path.join(data_dir,Token_file),'w') as f:
json.dump(token,f,ensure_ascii=False)
except:
with open(os.path.join(data_dir,'Atoken.json'),'r') as f:
with open(os.path.join(data_dir,'{}_Atoken.json'.format(user)),'r') as f:
Atoken=json.load(f)
refresh_token=Atoken.get('refresh_token')
token=ReFreshToken(refresh_token)
token=ReFreshToken(refresh_token,user)
token['expires_on']=str(time.time()+3599)
if token.get('access_token'):
with open(os.path.join(data_dir,Token_file),'w') as f:
@ -122,27 +125,7 @@ def GetToken(Token_file='token.json'):
def GetAppUrl():
global app_url
if os.path.exists(os.path.join(data_dir,'AppUrl')):
with open(os.path.join(data_dir,'AppUrl'),'r') as f:
app_url=f.read().strip()
return app_url
else:
# if od_type=='business':
# token=GetToken(Token_file='Atoken.json')
# print 'token:',token
# if token:
# header={'Authorization': 'Bearer {}'.format(token)}
# url='https://api.office.com/discovery/v1.0/me/services'
# r=requests.get(url,headers=header)
# retdata=json.loads(r.text)
# print retdata
# if retdata.get('value'):
# return retdata.get('value')[0]['serviceResourceId']
# return False
# else:
# return app_url
return app_url
return 'https://graph.microsoft.com/'
################################################################################
###############################onedrive操作函数#################################
@ -156,21 +139,23 @@ def GetExt(name):
def date_to_char(date):
return date.strftime('%Y/%m/%d')
def Dir(path=u'/'):
def Dir(path=u'A:/'):
app_url=GetAppUrl()
if path=='/':
user,n_path=path.split(':')
print('update {}\'s file'.format(user))
if n_path=='/':
BaseUrl=app_url+u'v1.0/me/drive/root/children?expand=thumbnails'
# items.remove()
queue=Queue()
# queue.put(dict(url=BaseUrl,grandid=grandid,parent=parent,trytime=1))
g=GetItemThread(queue)
g=GetItemThread(queue,user)
g.GetItem(BaseUrl)
queue=g.queue
if queue.qsize()==0:
return
tasks=[]
for i in range(min(5,queue.qsize())):
t=GetItemThread(queue)
t=GetItemThread(queue,user)
t.start()
tasks.append(t)
for t in tasks:
@ -178,60 +163,45 @@ def Dir(path=u'/'):
RemoveRepeatFile()
else:
grandid=0
parent_id=''
parent=None
if path.endswith('/'):
path=path[:-1]
if not path.startswith('/'):
path='/'+path
if items.find_one({'grandid':0,'type':'folder'}):
for idx,p in enumerate(path[1:].split('/')):
if parent_id=='':
parent=items.find_one({'name':p,'grandid':idx})
parent_id=parent['id']
else:
parent=items.find_one({'name':p,'grandid':idx,'parent':parent_id})
parent_id=parent['id']
# items.delete_many({'parent':parent_id})
grandid=idx+1
path=urllib.quote(path)
BaseUrl=app_url+u'v1.0/me/drive/root:{}:/children?expand=thumbnails'.format(path)
checkUrl=app_url+u'v1.0/me/drive/root:{}:/'.format(path)
parent=''
if n_path.endswith('/'):
n_path=n_path[:-1]
if not n_path.startswith('/'):
n_path='/'+n_path
n_path=urllib.quote(n_path)
BaseUrl=app_url+u'v1.0/me/drive/root:{}:/children?expand=thumbnails'.format(n_path)
queue=Queue()
# queue.put(dict(url=BaseUrl,grandid=grandid,parent=parent,trytime=1))
g=GetItemThread(queue)
# g.GetItem(BaseUrl,grandid,parent_id,1)
# queue=g.queue
# if queue.qsize()==0:
# return
if parent:
item_remote=g.GetItemByUrl(checkUrl)
if parent['size_order']==item_remote['size']:
return
g=GetItemThread(queue,user)
g.GetItem(BaseUrl,grandid,parent,1)
queue=g.queue
if queue.qsize()==0:
return
tasks=[]
for i in range(min(10,queue.qsize())):
t=GetItemThread(queue)
t=GetItemThread(queue,user)
t.start()
tasks.append(t)
for t in tasks:
t.join()
RemoveRepeatFile()
def Dir_all(path=u'/'):
def Dir_all(path=u'A:/'):
app_url=GetAppUrl()
if path=='/':
user,n_path=path.split(':')
print('update {}\'s {} file'.format(user,n_path))
if n_path=='/':
BaseUrl=app_url+u'v1.0/me/drive/root/children?expand=thumbnails'
items.remove()
items.remove({'user':user})
queue=Queue()
# queue.put(dict(url=BaseUrl,grandid=grandid,parent=parent,trytime=1))
g=GetItemThread(queue)
g=GetItemThread(queue,user)
g.GetItem(BaseUrl)
queue=g.queue
if queue.qsize()==0:
return
tasks=[]
for i in range(min(5,queue.qsize())):
t=GetItemThread(queue)
t=GetItemThread(queue,user)
t.start()
tasks.append(t)
for t in tasks:
@ -240,32 +210,31 @@ def Dir_all(path=u'/'):
else:
grandid=0
parent=''
if path.endswith('/'):
path=path[:-1]
if not path.startswith('/'):
path='/'+path
if items.find_one({'grandid':0,'type':'folder'}):
if n_path.endswith('/'):
n_path=n_path[:-1]
if not n_path.startswith('/'):
n_path='/'+n_path
if items.find_one({'grandid':0,'type':'folder','user':user}):
parent_id=0
for idx,p in enumerate(path[1:].split('/')):
for idx,p in enumerate(n_path[1:].split('/')):
if parent_id==0:
parent_id=items.find_one({'name':p,'grandid':idx})['id']
parent_id=items.find_one({'name':p,'grandid':idx,'user':user})['id']
else:
parent_id=items.find_one({'name':p,'grandid':idx,'parent':parent_id})['id']
items.delete_many({'parent':parent_id})
grandid=idx+1
parent=parent_id
path=urllib.quote(path)
BaseUrl=app_url+u'v1.0/me/drive/root:{}:/children?expand=thumbnails'.format(path)
n_path=urllib.quote(n_path)
BaseUrl=app_url+u'v1.0/me/drive/root:{}:/children?expand=thumbnails'.format(n_path)
queue=Queue()
# queue.put(dict(url=BaseUrl,grandid=grandid,parent=parent,trytime=1))
g=GetItemThread(queue)
g=GetItemThread(queue,user)
g.GetItem(BaseUrl,grandid,parent,1)
queue=g.queue
if queue.qsize()==0:
return
tasks=[]
for i in range(min(10,queue.qsize())):
t=GetItemThread(queue)
t=GetItemThread(queue,user)
t.start()
tasks.append(t)
for t in tasks:
@ -273,9 +242,11 @@ def Dir_all(path=u'/'):
RemoveRepeatFile()
class GetItemThread(Thread):
def __init__(self,queue):
def __init__(self,queue,user):
super(GetItemThread,self).__init__()
self.queue=queue
self.user=user
share_path=od_users.get(user).get('share_path')
if share_path=='/':
self.share_path=share_path
else:
@ -303,7 +274,7 @@ class GetItemThread(Thread):
def GetItem(self,url,grandid=0,parent='',trytime=1):
app_url=GetAppUrl()
token=GetToken()
token=GetToken(user=self.user)
print(u'getting files from url {}'.format(url))
header={'Authorization': 'Bearer {}'.format(token)}
try:
@ -326,6 +297,7 @@ class GetItemThread(Thread):
else:
items.delete_one({'id':value['id']})
item['type']='folder'
item['user']=self.user
item['order']=0
item['name']=convert2unicode(value['name'])
item['id']=convert2unicode(value['id'])
@ -343,6 +315,7 @@ class GetItemThread(Thread):
path=path[1:]
if path=='':
path=convert2unicode(value['name'])
path='{}:/{}'.format(self.user,path)
item['path']=path
subfodler=items.insert_one(item)
if value.get('folder').get('childCount')==0:
@ -364,7 +337,9 @@ class GetItemThread(Thread):
path=path[1:]
if path=='':
path=convert2unicode(value['name'])
path='{}:/{}'.format(self.user,path)
item['path']=path
item['user']=self.user
item['name']=convert2unicode(value['name'])
item['id']=convert2unicode(value['id'])
item['size']=humanize.naturalsize(value['size'], gnu=True)
@ -394,7 +369,7 @@ class GetItemThread(Thread):
def GetItemByPath(self,path):
app_url=GetAppUrl()
token=GetToken()
token=GetToken(user=self.user)
if path=='' or path=='/':
url=app_url+u'v1.0/me/drive/root/'
if path=='/':
@ -407,19 +382,19 @@ class GetItemThread(Thread):
def GetItemByUrl(self,url):
app_url=GetAppUrl()
token=GetToken()
token=GetToken(user=self.user)
header={'Authorization': 'Bearer {}'.format(token)}
r=requests.get(url,headers=header)
data=json.loads(r.content)
return data
def GetRootid():
key='rootid'
def GetRootid(user='A'):
key='{}:rootid'.format(user)
if rd.exists(key):
return rd.get(key)
else:
app_url=GetAppUrl()
token=GetToken()
token=GetToken(user=user)
url=app_url+u'v1.0/me/drive/root/'
header={'Authorization': 'Bearer {}'.format(token)}
r=requests.get(url,headers=header)
@ -430,14 +405,20 @@ def GetRootid():
def UpdateFile(renew='all'):
if renew=='all':
items.remove()
Dir_all(share_path)
for user,item in od_users.items():
if item.get('client_id')!='':
share_path='{}:{}'.format(user,item['share_path'])
Dir_all(share_path)
else:
Dir(share_path)
for user,item in od_users.items():
if item.get('client_id')!='':
share_path='{}:{}'.format(user,item['share_path'])
Dir(share_path)
print('update file success!')
def FileExists(filename):
token=GetToken()
def FileExists(filename,user='A'):
token=GetToken(user=user)
headers={'Authorization':'bearer {}'.format(token),'Content-Type':'application/json'}
search_url=app_url+"v1.0/me/drive/root/search(q='{}')".format(filename)
r=requests.get(search_url,headers=headers)
@ -447,8 +428,8 @@ def FileExists(filename):
else:
return True
def FileInfo(fileid):
token=GetToken()
def FileInfo(fileid,user='A'):
token=GetToken(user=user)
headers={'Authorization':'bearer {}'.format(token),'Content-Type':'application/json'}
search_url=app_url+"v1.0/me/drive/items/{}".format(fileid)
r=requests.get(search_url,headers=headers)
@ -501,8 +482,8 @@ def _file_content(path,offset,length):
def _upload(filepath,remote_path): #remote_path like 'share/share.mp4'
token=GetToken()
def _upload(filepath,remote_path,user='A'): #remote_path like 'share/share.mp4'
token=GetToken(user=user)
headers={'Authorization':'bearer {}'.format(token)}
url=app_url+'v1.0/me/drive/root:'+urllib.quote(remote_path)+':/content'
r=requests.put(url,headers=headers,data=open(filepath,'rb'))
@ -516,7 +497,7 @@ def _upload(filepath,remote_path): #remote_path like 'share/share.mp4'
break
elif r.status_code==201 or r.status_code==200:
print('upload {} success!'.format(filepath))
AddResource(data)
AddResource(data,user)
yield {'status':'upload success!'}
break
else:
@ -589,7 +570,7 @@ def _GetAllFile(parent_id="",parent_path="",filelist=[]):
return filelist
def AddResource(data):
def AddResource(data,user='A'):
#检查父文件夹是否在数据库,如果不在则获取添加
grand_path=data.get('parentReference').get('path').replace('/drive/root:','')
if grand_path=='':
@ -625,6 +606,7 @@ def AddResource(data):
item={}
item['type']='file'
item['name']=data.get('name')
item['user']=user
item['id']=data.get('id')
item['size']=humanize.naturalsize(data.get('size'), gnu=True)
item['size_order']=data.get('size')
@ -653,8 +635,8 @@ def AddResource(data):
items.insert_one(item)
def CreateUploadSession(path):
token=GetToken()
def CreateUploadSession(path,user='A'):
token=GetToken(user=user)
headers={'Authorization':'bearer {}'.format(token),'Content-Type':'application/json'}
url=app_url+'v1.0/me/drive/root:'+urllib.quote(path)+':/createUploadSession'
data={
@ -674,8 +656,7 @@ def CreateUploadSession(path):
print('error to opreate CreateUploadSession("{}"),reason {}'.format(path,e))
return False
def UploadSession(uploadUrl, filepath):
token=GetToken()
def UploadSession(uploadUrl, filepath,user):
length=327680*10
offset=0
trytime=1
@ -685,7 +666,7 @@ def UploadSession(uploadUrl, filepath):
code=result['code']
#上传完成
if code==0:
AddResource(result['info'])
AddResource(result['info'],user)
yield {'status':'upload success!'}
break
#分片上传成功
@ -710,8 +691,8 @@ def UploadSession(uploadUrl, filepath):
def Upload_for_server(filepath,remote_path=None):
token=GetToken()
def Upload_for_server(filepath,remote_path=None,user='A'):
token=GetToken(user=user)
headers={'Authorization':'bearer {}'.format(token),'Content-Type':'application/json'}
if remote_path is None:
remote_path=os.path.basename(filepath)
@ -721,24 +702,24 @@ def Upload_for_server(filepath,remote_path=None):
remote_path='/'+remote_path
print('local file path:{}, remote file path:{}'.format(filepath,remote_path))
if _filesize(filepath)<1024*1024*3.25:
for msg in _upload(filepath,remote_path):
for msg in _upload(filepath,remote_path,user):
yield msg
else:
session_data=CreateUploadSession(remote_path)
session_data=CreateUploadSession(remote_path,user)
if session_data==False:
yield {'status':'file exists!'}
else:
if session_data.get('uploadUrl'):
uploadUrl=session_data.get('uploadUrl')
for msg in UploadSession(uploadUrl,filepath):
for msg in UploadSession(uploadUrl,filepath,user):
yield msg
else:
print(session_data.get('error').get('msg'))
print('create upload session fail! {}'.format(remote_path))
yield {'status':'create upload session fail!'}
def Upload(filepath,remote_path=None):
token=GetToken()
def Upload(filepath,remote_path=None,user='A'):
token=GetToken(user=user)
headers={'Authorization':'bearer {}'.format(token),'Content-Type':'application/json'}
if remote_path is None:
remote_path=os.path.basename(filepath)
@ -747,16 +728,16 @@ def Upload(filepath,remote_path=None):
if not remote_path.startswith('/'):
remote_path='/'+remote_path
if _filesize(filepath)<1024*1024*3.25:
for msg in _upload(filepath,remote_path):
for msg in _upload(filepath,remote_path,user):
1
else:
session_data=CreateUploadSession(remote_path)
session_data=CreateUploadSession(remote_path,user)
if session_data==False:
return {'status':'file exists!'}
else:
if session_data.get('uploadUrl'):
uploadUrl=session_data.get('uploadUrl')
for msg in UploadSession(uploadUrl,filepath):
for msg in UploadSession(uploadUrl,filepath,user):
1
else:
print(session_data.get('error').get('msg'))
@ -765,17 +746,18 @@ def Upload(filepath,remote_path=None):
class MultiUpload(Thread):
def __init__(self,waiting_queue):
def __init__(self,waiting_queue,user):
super(MultiUpload,self).__init__()
self.queue=waiting_queue
self.user=user
def run(self):
while not self.queue.empty():
localpath,remote_dir=self.queue.get()
Upload(localpath,remote_dir)
Upload(localpath,remote_dir,self.user)
def UploadDir(local_dir,remote_dir,threads=5):
def UploadDir(local_dir,remote_dir,user,threads=5):
print(u'geting file from dir {}'.format(local_dir))
localfiles=list_all_files(local_dir)
print(u'get {} files from dir {}'.format(len(localfiles),local_dir))
@ -827,7 +809,7 @@ def UploadDir(local_dir,remote_dir,threads=5):
print "start upload files 5s later"
time.sleep(5)
for i in range(min(threads,queue.qsize())):
t=MultiUpload(queue)
t=MultiUpload(queue,user)
t.start()
tasks.append(t)
for t in tasks:
@ -841,9 +823,9 @@ def UploadDir(local_dir,remote_dir,threads=5):
def DeleteLocalFile(fileid):
items.remove({'id':fileid})
def DeleteRemoteFile(fileid):
def DeleteRemoteFile(fileid,user='A'):
app_url=GetAppUrl()
token=GetToken()
token=GetToken(user=user)
headers={'Authorization':'bearer {}'.format(token)}
url=app_url+'v1.0/me/drive/items/'+fileid
r=requests.delete(url,headers=headers)
@ -855,15 +837,16 @@ def DeleteRemoteFile(fileid):
return False
########################
def CreateFolder(folder_name,grand_path):
def CreateFolder(folder_name,grand_path,user='A'):
app_url=GetAppUrl()
token=GetToken()
token=GetToken(user=user)
if grand_path=='' or grand_path is None or grand_path=='/':
url=app_url+'v1.0/me/drive/root/children'
parent_id=''
grandid=0
else:
parent=items.find_one({'path':grand_path})
path='{}:/{}'.format(user,grand_path)
parent=items.find_one({'path':path})
parent_id=parent['id']
grandid=parent['grandid']+1
url=app_url+'v1.0/me/drive/items/{}/children'.format(parent['id'])
@ -877,8 +860,10 @@ def CreateFolder(folder_name,grand_path):
data=json.loads(r.content)
if data.get('id'):
#插入数据
share_path=od_users.get(user).get('share_path')
item={}
item['type']='folder'
item['user']=user
item['name']=data.get('name')
item['id']=data.get('id')
item['size']=humanize.naturalsize(data.get('size'), gnu=True)
@ -890,27 +875,29 @@ def CreateFolder(folder_name,grand_path):
path=convert2unicode(data['name'])
else:
path=grand_path.replace(share_path,'',1)+'/'+convert2unicode(data['name'])
if path.startswith('/') and path!='/':
path=path[1:]
if not path.startswith('/'):
path='/'+path
path='{}:{}'.format(user,path)
item['path']=path
item['order']=2
item['order']=0
items.insert_one(item)
return True
else:
print(data.get('error').get('msg'))
return False
def MoveFile(fileid,new_folder_path):
def MoveFile(fileid,new_folder_path,user='A'):
app_url=GetAppUrl()
token=GetToken()
token=GetToken(user=user)
#GetRootid
if new_folder_path=='' or new_folder_path is None or new_folder_path=='/':
folder_id=GetRootid()
folder_id=GetRootid(user)
parent=''
grandid=0
path=GetName(fileid)
else:
parent_item=items.find_one({'path':new_folder_path})
path='{}:/{}'.format(user,new_folder_path)
parent_item=items.find_one({'path':path})
folder_id=parent_item['id']
parent=parent_item['id']
grandid=parent_item['grandid']+1

131
run.py

@ -1,3 +1,4 @@
#-*- coding=utf-8 -*-
from flask import Flask,render_template,redirect,abort,make_response,jsonify,request,url_for,Response
from flask_sqlalchemy import Pagination
@ -43,23 +44,24 @@ def md5(string):
a.update(string.encode(encoding='utf-8'))
return a.hexdigest()
def GetTotal(path):
def GetTotal(path='A:/'):
key='total:{}'.format(path)
if rd.exists(key):
return int(rd.get(key))
else:
if path=='/':
user,n_path=path.split(':')
if n_path=='/':
total=items.find({'grandid':0}).count()
else:
f=items.find_one({'path':path})
pid=f['id']
total=items.find({'parent':pid}).count()
rd.set(key,total,300)
rd.set(key,total,300)
return total
# @cache.memoize(timeout=60*5)
def FetchData(path='/',page=1,per_page=50,sortby='lastModtime',order='desc',dismiss=False):
def FetchData(path='A:/',page=1,per_page=50,sortby='lastModtime',order='desc',dismiss=False):
path=urllib.unquote(path)
resp=[]
if sortby not in ['lastModtime','type','size','name']:
@ -71,8 +73,9 @@ def FetchData(path='/',page=1,per_page=50,sortby='lastModtime',order='desc',dism
else:
order=ASCENDING
try:
if path=='/':
data=items.find({'grandid':0}).collation({"locale": "zh", 'numericOrdering':True})\
user,n_path=path.split(':')
if n_path=='/':
data=items.find({'grandid':0,'user':user}).collation({"locale": "zh", 'numericOrdering':True})\
.sort([('order',ASCENDING),(sortby,order)])\
.limit(per_page).skip((page-1)*per_page)
for d in data:
@ -115,9 +118,9 @@ def FetchData(path='/',page=1,per_page=50,sortby='lastModtime',order='desc',dism
return resp,total
@cache.memoize(timeout=60*5)
def _thunbnail(id):
def _thunbnail(id,user):
app_url=GetAppUrl()
token=GetToken()
token=GetToken(user=user)
headers={'Authorization':'bearer {}'.format(token),'Content-type':'application/json'}
url=app_url+'v1.0/me/drive/items/{}/thumbnails/0?select=large'.format(id)
r=requests.get(url,headers=headers)
@ -128,13 +131,13 @@ def _thunbnail(id):
return False
@cache.memoize(timeout=60*5)
def _getdownloadurl(id):
def _getdownloadurl(id,user):
app_url=GetAppUrl()
token=GetToken()
token=GetToken(user=user)
filename=GetName(id)
ext=filename.split('.')[-1]
if ext in ['webm','avi','mpg', 'mpeg', 'rm', 'rmvb', 'mov', 'wmv', 'mkv', 'asf']:
downloadUrl=_thunbnail(id)
downloadUrl=_thunbnail(id,user)
downloadUrl=downloadUrl.replace('thumbnail','videomanifest')+'&part=index&format=dash&useScf=True&pretranscode=0&transcodeahead=0'
return downloadUrl
else:
@ -147,12 +150,12 @@ def _getdownloadurl(id):
else:
return False
def GetDownloadUrl(id):
def GetDownloadUrl(id,user):
if rd.exists('downloadUrl2:{}'.format(id)):
downloadUrl,ftime=rd.get('downloadUrl2:{}'.format(id)).split('####')
if time.time()-int(ftime)>=600:
# print('{} downloadUrl expired!'.format(id))
downloadUrl=_getdownloadurl(id)
downloadUrl=_getdownloadurl(id,user)
ftime=int(time.time())
k='####'.join([downloadUrl,str(ftime)])
rd.set('downloadUrl2:{}'.format(id),k)
@ -161,7 +164,7 @@ def GetDownloadUrl(id):
downloadUrl=downloadUrl
else:
# print('first time get downloadUrl from {}'.format(id))
downloadUrl=_getdownloadurl(id)
downloadUrl=_getdownloadurl(id,user)
ftime=int(time.time())
k='####'.join([downloadUrl,str(ftime)])
rd.set('downloadUrl2:{}'.format(id),k)
@ -240,12 +243,12 @@ def file_ico(item):
return "insert_drive_file";
def _remote_content(fileid):
def _remote_content(fileid,user):
kc='{}:content'.format(fileid)
if rd.exists(kc):
return rd.get(kc)
else:
downloadUrl=GetDownloadUrl(fileid)
downloadUrl=GetDownloadUrl(fileid,user)
if downloadUrl:
r=requests.get(downloadUrl)
r.encoding='utf-8'
@ -280,10 +283,11 @@ def has_item(path,name):
if name=='.password':
dz=True
try:
if path=='/':
if items.find_one({'grandid':0,'name':name}):
fid=items.find_one({'grandid':0,'name':name})['id']
item=_remote_content(fid).strip()
user,n_path=path.split(':')
if n_path=='/':
if items.find_one({'grandid':0,'name':name,'user':user}):
fid=items.find_one({'grandid':0,'name':name,'user':user})['id']
item=_remote_content(fid,user).strip()
else:
route=path.split('/')
if name=='.password':
@ -294,7 +298,7 @@ def has_item(path,name):
data=items.find_one({'name':name,'parent':pid})
if data:
fid=data['id']
item=_remote_content(fid).strip()
item=_remote_content(fid,user).strip()
if idx==len(route)-1:
cur=True
else:
@ -303,7 +307,7 @@ def has_item(path,name):
data=items.find_one({'name':name,'parent':pid})
if data:
fid=data['id']
item=_remote_content(fid).strip()
item=_remote_content(fid,user).strip()
except:
item=False
rd.set(key,'{}########{}########{}'.format(item,fid,cur))
@ -337,16 +341,54 @@ def has_verify(path):
def path_list(path):
if path=='/':
return [path]
if path.startswith('/'):
path=path[1:]
if path.endswith('/'):
path=path[:-1]
plist=path.split('/')
if path.split(':')=='':
plist=[path+'/']
else:
user,n_path=path.split(':')
if n_path.startswith('/'):
n_path=n_path[1:]
if n_path.endswith('/'):
n_path=n_path[:-1]
plist=n_path.split('/')
plist=['{}:/{}'.format(user,plist[0])]+plist[1:]
return plist
def get_od_user():
config_path=os.path.join(config_dir,'config.py')
with open(config_path,'r') as f:
text=f.read()
users=json.loads(re.findall('od_users=([\w\W]*})',text)[0])
ret=[]
for user,value in users.items():
if value.get('client_id')!='':
#userid,username,endpoint,sharepath,order,
ret.append(
(
user,
value.get('other_name'),
'/{}:'.format(user),
value.get('share_path'),
value.get('order')
)
)
else:
ret.append(
(
user,
'添加网盘',
url_for('admin.install',step=0,user=user),
value.get('share_path'),
value.get('order')
)
)
ret=sorted(ret,key=lambda x:x[-1],reverse=False)
return ret
################################################################################
###################################试图函数#####################################
################################################################################
@ -370,23 +412,26 @@ def before_request():
@app.route('/<path:path>',methods=['POST','GET'])
@app.route('/',methods=['POST','GET'])
@limiter.limit("200/minute;50/second")
def index(path='/'):
def index(path='A:/'):
if path=='favicon.ico':
return redirect('https://onedrive.live.com/favicon.ico')
if items.count()==0:
if not os.path.exists(os.path.join(config_dir,'data/token.json')):
return redirect(url_for('admin.install',step=0))
if not os.path.exists(os.path.join(config_dir,'data/.install')):
return redirect(url_for('admin.install',step=0,user='A'))
else:
#subprocess.Popen('python {} UpdateFile'.format(os.path.join(config_dir,'function.py')),shell=True)
return make_response('<h1>正在更新数据!如果您是网站管理员,请在后台运行命令:python function.py UpdateFile</h1>')
#参数
user,n_path=path.split(':')
if n_path=='':
path=':'.join([user,'/'])
page=request.args.get('page',1,type=int)
image_mode=request.args.get('image_mode')
sortby=request.args.get('sortby')
order=request.args.get('order')
resp,total = FetchData(path=path,page=page,per_page=50,sortby=sortby,order=order,dismiss=True)
if total=='files':
return show(resp['id'])
return show(resp['id'],user)
#是否有密码
password,_,cur=has_item(path,'.password')
md5_p=md5(path)
@ -422,6 +467,8 @@ def index(path='/'):
#参数
resp,total = FetchData(path=path,page=page,per_page=50,sortby=sortby,order=order,dismiss=True)
pagination=Pagination(query=None,page=page, per_page=50, total=total, items=None)
if path.split(':',1)[-1]=='/':
path=':'.join([path.split(':',1)[0],''])
resp=make_response(render_template('index.html'
,pagination=pagination
,items=resp
@ -433,21 +480,22 @@ def index(path='/'):
,ext_d=ext_d
,sortby=sortby
,order=order
,cur_user=user
,endpoint='.index'))
resp.set_cookie('image_mode',str(image_mode))
resp.set_cookie('sortby',str(sortby))
resp.set_cookie('order',str(order))
return resp
@app.route('/file/<fileid>')
def show(fileid):
@app.route('/file/<user>/<fileid>')
def show(fileid,user):
name=GetName(fileid)
ext=name.split('.')[-1].lower()
path=GetPath(fileid)
if request.method=='POST':
url=request.url.replace(':80','').replace(':443','')
if ext in ['csv','doc','docx','odp','ods','odt','pot','potm','potx','pps','ppsx','ppsxm','ppt','pptm','pptx','rtf','xls','xlsx']:
downloadUrl=GetDownloadUrl(fileid)
downloadUrl=GetDownloadUrl(fileid,user)
url = 'https://view.officeapps.live.com/op/view.aspx?src='+urllib.quote(downloadUrl)
return redirect(url)
elif ext in ['bmp','jpg','jpeg','png','gif']:
@ -461,18 +509,18 @@ def show(fileid):
elif ext in ['ogg','mp3','wav']:
return render_template('show/audio.html',url=url,path=path)
elif CodeType(ext) is not None:
content=_remote_content(fileid)
content=_remote_content(fileid,user)
return render_template('show/code.html',content=content,url=url,language=CodeType(ext),path=path)
else:
downloadUrl=GetDownloadUrl(fileid)
downloadUrl=GetDownloadUrl(fileid,user)
return redirect(downloadUrl)
else:
if 'no-referrer' in allow_site:
downloadUrl=GetDownloadUrl(fileid)
downloadUrl=GetDownloadUrl(fileid,user)
resp=redirect(downloadUrl)
return resp
elif sum([i in referrer for i in allow_site])>0:
downloadUrl=GetDownloadUrl(fileid)
downloadUrl=GetDownloadUrl(fileid,user)
return redirect(downloadUrl)
else:
return abort(404)
@ -504,8 +552,9 @@ app.jinja_env.globals['re']=re
app.jinja_env.globals['file_ico']=file_ico
app.jinja_env.globals['title']=title
app.jinja_env.globals['tj_code']=tj_code if tj_code is not None else ''
app.jinja_env.globals['get_od_user']=get_od_user
app.jinja_env.globals['allow_site']=','.join(allow_site)
app.jinja_env.globals['share_path']=share_path
# app.jinja_env.globals['share_path']=od_users.get('A').get('share_path')
app.jinja_env.globals['downloadUrl_timeout']=downloadUrl_timeout
################################################################################
#####################################启动#######################################

@ -1 +1,121 @@
body{background-color:#f2f5fa;padding-bottom:60px;background-image:url(../img/bg-bottom.svg);background-position:50% 100%;background-repeat:no-repeat;background-attachment:fixed}.nexmoe-item{margin:20px -8px 0!important;padding:15px!important;border-radius:5px;background-color:#fff;-webkit-box-shadow:0 .5em 3em rgba(161,177,204,.4);box-shadow:0 .5em 3em rgba(161,177,204,.4);background-color:#fff}.mdui-img-fluid,.mdui-video-fluid{border-radius:5px;border:1px solid #eee}.mdui-list{padding:0}.mdui-list-item{margin:0!important;border-radius:5px;padding:0 10px 0 5px!important;border:1px solid #eee;margin-bottom:10px!important}.mdui-list-item:last-child{margin-bottom:0!important}.mdui-list-item:first-child{border:none}.mdui-toolbar{width:auto;margin-top:60px!important}.mdui-appbar .mdui-toolbar{height:56px;font-size:16px}.mdui-toolbar>*{padding:0 6px;margin:0 2px;opacity:.5}.mdui-toolbar>.mdui-typo-headline{padding:0 16px 0 0}.mdui-toolbar>i{padding:0}.mdui-toolbar>a:hover,a.mdui-typo-headline,a.active{opacity:1}.mdui-container{max-width:980px}.mdui-list>.th{background-color:initial}.mdui-list-item>a{width:100%;line-height:48px}.mdui-toolbar>a{padding:0 16px;line-height:30px;border-radius:30px;border:1px solid #eee}.mdui-toolbar>a:last-child{opacity:1;background-color:#1e89f2;color:#ffff}@media screen and (max-width:980px){.mdui-list-item .mdui-text-right{display:none}.mdui-container{width:100%!important;margin:0}.mdui-toolbar>*{display:none}.mdui-toolbar>a:last-child,.mdui-toolbar>.mdui-typo-headline,.mdui-toolbar>i:first-child{display:block}}
body {
background-color: #f2f5fa;
padding-bottom: 60px;
background-image: url(../img/bg-bottom.svg);
background-position: 50% 100%;
background-repeat: no-repeat;
background-attachment: fixed
}
.nexmoe-item {
/*margin: 20px -8px 0 !important;*/
padding: 15px !important;
border-radius: 5px;
background-color: #fff;
-webkit-box-shadow: 0 .5em 3em rgba(161, 177, 204, .4);
box-shadow: 0 .5em 3em rgba(161, 177, 204, .4);
background-color: #fff
}
.mdui-img-fluid,
.mdui-video-fluid {
border-radius: 5px;
border: 1px solid #eee
}
.mdui-list {
padding: 0
}
.mdui-list-item {
margin: 0 !important;
border-radius: 5px;
padding: 0 10px 0 5px !important;
border: 1px solid #eee;
margin-bottom: 10px !important
}
.mdui-list-item:last-child {
margin-bottom: 0 !important
}
.mdui-list-item:first-child {
border: none
}
.mdui-toolbar {
width: auto;
/*margin-top: 60px !important*/
}
.mdui-appbar .mdui-toolbar {
height: 56px;
font-size: 16px
}
.mdui-toolbar>* {
padding: 0 6px;
margin: 0 2px;
opacity: .5
}
.mdui-toolbar>.mdui-typo-headline {
padding: 0 16px 0 0
}
.mdui-toolbar>i {
padding: 0
}
.mdui-toolbar>a:hover,
a.mdui-typo-headline,
a.active {
opacity: 1
}
.mdui-container {
max-width: 980px
}
.mdui-list>.th {
background-color: initial
}
.mdui-list-item>a {
width: 100%;
line-height: 48px
}
.mdui-toolbar>a {
padding: 0 16px;
line-height: 30px;
border-radius: 30px;
border: 1px solid #eee
}
.mdui-toolbar>a:last-child {
opacity: 1;
background-color: #1e89f2;
color: #ffff
}
@media screen and (max-width:980px) {
.mdui-list-item .mdui-text-right {
display: none
}
.mdui-container {
width: 100% !important;
margin: 0
}
.mdui-toolbar>* {
display: none
}
.mdui-toolbar>a:last-child,
.mdui-toolbar>.mdui-typo-headline,
.mdui-toolbar>i:first-child {
display: block
}
}

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 49 KiB

@ -0,0 +1,34 @@
[unix_http_server]
file=/tmp/supervisor.sock
[supervisord]
logfile=/tmp/supervisord.log
logfile_maxbytes=50MB
logfile_backups=10
loglevel=info
pidfile=/tmp/supervisord.pid
nodaemon=false
minfds=1024
minprocs=200
[inet_http_server] ; inet (TCP) server disabled by default
port=*:9001
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock
[program:pyone]
command = gunicorn -k eventlet -b 0.0.0.0:34567 run:app
directory = /root/PyOne
autorestart = true
[program:online]
command = gunicorn -k eventlet -b 0.0.0.0:34568 run:app
directory = /root/vv2
autorestart = true

@ -15,20 +15,22 @@
<div class="mdui-row">
<form action="" method="post">
<div class="mdui-col-xs-10">
<div class="mdui-textfield">
<label class="mdui-textfield-label">更新目录 <small>默认为/,即更新全部文件;更新特定目录,比如91porn,则设置为91porn</small></label>
<input name="dir" class="mdui-textfield-input" type="text" value="{%if dir%}{{dir}}{%else%}/{%endif%}"/>
</div>
<label class="mdui-textfield-label">更新规则</label>
<select class="mdui-select" name="type" mdui-select>
<option value="new">增量更新</option>
<option value="all">全量更新</option>
</select>
</div>
<div class="mdui-col-xs-2" style="padding-top: 34px;">
<!-- <div class="mdui-col-xs-7">
<label class="mdui-textfield-label">更新目录 <small>默认为/,即更新全部文件;更新特定目录,比如91porn,则设置为91porn</small></label>
<input name="dir" class="mdui-textfield-input" type="text" value="{%if dir%}{{dir}}{%else%}/{%endif%}"/>
</div> -->
<div class="mdui-col-xs-2">
<button type="submit" name="refresh" class="mdui-btn mdui-btn-block mdui-color-green-600 mdui-ripple">
<i class="mdui-icon material-icons">&#xe028;</i>
更新缓存
</button>
</div>
<br><br><br>
<center class="mdui-typo-headline-opacity mdui-text-color-green"><?php echo $message;?></center>
<br><br><br>
</form>
</div>
@ -38,8 +40,8 @@
</div>
</div>
<script>
{%if dir%}
var source = new EventSource("{{url_for('admin.web_console',dir=dir,action=action)|safe}}");
{%if type%}
var source = new EventSource("{{url_for('admin.web_console',type=type,action=action)|safe}}");
source.onmessage = function(event) {
if(event.data=='end'){
source.close();

@ -39,7 +39,7 @@
type: "POST",
url: "{{url_for('admin.edit')}}",
dataType:'json',
data: {fileid:fileid,content:content},
data: {fileid:fileid,content:content,user:"{{cur_user}}"},
beforeSend:function(xhr){
var index = layer.load(2, {
shade: [0.1,'#fff'] //0.1透明度的白色背景

@ -30,6 +30,7 @@
</div>
<br>
<input type="hidden" name="step" value="1">
<input type="hidden" name="user" value="{{cur_user}}">
<br>
<br>
<button class="mdui-btn mdui-color-theme-accent mdui-ripple mdui-float-right" type="submit">下一步</button>

@ -10,7 +10,7 @@
<div class="mdui-typo">
<h4>步骤1:绑定账号,获取code</h4>
</div>
<div class="mdui-typo">
<h4>步骤2:输入code,结束绑定</h4>
<a href="{{login_url}}" class="mdui-btn mdui-color-theme-accent mdui-ripple mdui-float-right" target="_blank">1. 绑定账号</a>
@ -21,6 +21,7 @@
<input type="text" type="text" class="mdui-textfield-input" name="code" required"/>
<div class="mdui-textfield-error">code不能为空</div>
</div>
<input type="hidden" name="user" value="{{cur_user}}">
<input type="hidden" name="step" value="2">
<input type="hidden" name="client_id" value="{{client_id}}">
<input type="hidden" name="client_secret" value="{{client_secret}}">
@ -32,7 +33,7 @@
<div class="mdui-typo">
<h4>示例,如何操作</h4>
<img src="https://i.loli.net/2018/09/23/5ba7342b84ed5.png">
</div>
</div>
</div>
{%endblock content%}

@ -42,7 +42,7 @@
<br><br>
<a href="{{url_for('admin.setting')}}" class="mdui-list-item">
<i class="mdui-list-item-icon mdui-icon material-icons">&#xe8b8;</i>
<div class="mdui-list-item-content">基本设置(保存请重启)</div>
<div class="mdui-list-item-content">基本设置</div>
</a>
<a href="{{url_for('admin.upload')}}" class="mdui-list-item">

@ -1,4 +1,4 @@
{%extends 'layout.html'%}
{%extends 'admin/layout.html'%}
{%block content%}
<div class="mdui-container-fluid">

@ -25,6 +25,31 @@ a:hover {
<h1> 文件管理 <small>仅支持更新/编辑文编;支持删除文件</small></h1>
</div>
<div class="mdui-table-fluid">
<div class="mdui-appbar mdui-appbar-scroll-hide">
<div class="mdui-tab mdui-color-theme" mdui-tab>
{%for user in get_od_user()%}
{%if user[1]!='添加网盘'%}
<a href="{{url_for('admin.manage',path=user[0]+':/')}}" class="mdui-ripple mdui-ripple-white{%if cur_user==user[0]%} mdui-tab-active{%endif%}" id="{{user[0]}}">
<i class="mdui-icon material-icons">&#xe2bf;</i>
<label>{{user[1]}}</label>
</a>
{%endif%}
{%endfor%}
</div>
<div class="mdui-toolbar nexmoe-item">
<a href="/">{{cur_user}}</a>
{%if path%}
{%for idx,p in enumerate(path_list(path))%}
<i class="mdui-icon material-icons mdui-icon-dark" style="margin:0;">chevron_right</i>
{%if idx==len(path_list(path))-1%}
<a href="{{url_for('admin.manage',path=cur_user+':/')}}">{{p|replace(cur_user+':/','')|replace(cur_user+':','')}}</a>
{%else%}
<a href="{{url_for('admin.manage',path='/'.join(path_list(path)[:idx+1]))}}">{{p|replace(cur_user+':/','')|replace(cur_user+':','')}}</a>
{%endif%}
{%endfor%}
{%endif%}
</div>
</div>
<table class="mdui-table mdui-table-selectable">
<thead>
<tr>
@ -46,13 +71,19 @@ a:hover {
</tr>
</thead>
<tbody>
{%if path!='/'%}
{%if path.split(':')[-1]!=''%}
<tr>
<td></td>
<td>
<a href="{{url_for('admin.manage',path='/'.join(path_list(path)[:-1]))|safe}}">
<i class="mdui-icon material-icons">arrow_upward</i> 返回上一层
</a>
{%if '/'.join(path_list(path)[:-1])==''%}
<a href="{{url_for('admin.manage',path=cur_user+':/')|safe}}">
<i class="mdui-icon material-icons">arrow_upward</i> 返回上一层
</a>
{%else%}
<a href="{{url_for('admin.manage',path='/'.join(path_list(path))[:-1])|safe}}">
<i class="mdui-icon material-icons">arrow_upward</i> 返回上一层
</a>
{%endif%}
</td>
<td></td>
<td></td>
@ -67,9 +98,9 @@ a:hover {
</label>
</td>
<td>
<a href="{{url_for('admin.manage',path=os.path.join(path,data['name']))|safe}}" class="mdui-list-item">
<i class="mdui-icon material-icons">folder_open</i> {{data['name']}}
</a>
<a href="{{url_for('admin.manage',path=path+'/'+data['name'])|safe}}" class="mdui-list-item">
<i class="mdui-icon material-icons">folder_open</i> {{data['name']}}
</a>
</td>
<td>{{data['lastModtime']}}</td>
<td>
@ -86,9 +117,9 @@ a:hover {
</label>
</td>
<td class="file">
<a href="{{url_for('index',path=path+'/'+data['name'])}}" target="_blank" class="mdui-list-item">
<i class="mdui-icon material-icons">{{file_ico(data)}}</i> {{data['name']}}
</a>
<a href="{{url_for('index',path=path+'/'+data['name'])|safe}}" target="_blank" class="mdui-list-item">
<i class="mdui-icon material-icons">{{file_ico(data)}}</i> {{data['name']}}
</a>
</td>
<td>{{data['lastModtime']}}</td>
<td>
@ -142,7 +173,7 @@ function delAllProduct() {
}
var cks = document.getElementsByName("choice");
var str = "";
//拼接所有的图书id
//拼接所有id
for (var i = 0; i < cks.length; i++) {
if (cks[i].checked) {
str += cks[i].value + "##";
@ -155,7 +186,7 @@ function delAllProduct() {
type: "POST",
url: "{{url_for('admin.delete')}}",
dataType: 'json',
data: { id: str },
data: { id: str,user:"{{cur_user}}" },
beforeSend: function(xhr) {
var index = layer.load(2, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
@ -185,7 +216,7 @@ function delProduct(id) {
type: "POST",
url: "{{url_for('admin.delete')}}",
dataType: 'json',
data: { id: id },
data: { id: id ,user:"{{cur_user}}"},
beforeSend: function(xhr) {
var index = layer.load(2, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
@ -208,7 +239,7 @@ function delProduct(id) {
}
function editFile(id) {
window.open("{{url_for('admin.edit')}}?fileid=" + id, '_blank');
window.open("{{url_for('admin.edit')}}?fileid=" + id+"&user={{cur_user}}", '_blank');
}
function setPasswd(path) {
@ -237,7 +268,7 @@ function moveProduct(fileid){
$.ajax({
type: "POST",
url: "{{url_for('admin.MoveFileToNewFolder')}}",
data: { fileid: fileid,new_folder_path:value },
data: { fileid: fileid,new_folder_path:value,user:"{{cur_user}}" },
async: false,//使用同步的方式,true为异步方式
dataType: "json",
beforeSend: function(xhr) {

@ -12,11 +12,6 @@
<input class="mdui-textfield-input" type="text" name="title" value="{{title}}"/>
</div>
<div class="mdui-textfield">
<h4>分享目录<small>例:仅共享share目录 /share</small></h4>
<input class="mdui-textfield-input" type="text" name="share_path" value="{{share_path}}"/>
</div>
<div class="mdui-textfield">
<h4>缓存过期时间(秒)</h4>
<input class="mdui-textfield-input" type="text" name="downloadUrl_timeout" value="{{downloadUrl_timeout}}"/>
@ -38,6 +33,25 @@
<input class="mdui-textfield-input" type="password" name="password2" placeholder="请再次输入新密码" />
</div>
<div class="mdui-textfield">
<h4>网盘信息编辑</h4>
{%for user in get_od_user()%}
{%if user[1]!='添加网盘'%}
<div class="mdui-panel" mdui-panel>
<div class="mdui-panel-item">
<div class="mdui-panel-item-header">{{user[1]}}</div>
<div class="mdui-panel-item-body">
<h5>显示名称</h5>
<input class="mdui-textfield-input" type="text" name="other_name[{{user[0]}}]" placeholder="请输入显示名称" value="{{user[1]}}" />
<h5>分享目录</h5>
<input class="mdui-textfield-input" type="text" name="share_path[{{user[0]}}]" placeholder="请输入分享目录" value="{{user[3]}}" />
</div>
</div>
</div>
{%endif%}
{%endfor%}
</div>
<button type="submit" class="mdui-btn mdui-color-theme-accent mdui-ripple mdui-float-right">
<i class="mdui-icon material-icons">&#xe161;</i> 保存
</button>

@ -14,17 +14,23 @@
</div>
<div class="mdui-row">
<form action="" method="post">
<div class="mdui-col-xs-7">
<div class="mdui-textfield">
<div class="mdui-col-xs-3">
<label class="mdui-textfield-label">选择网盘</label>
<select class="mdui-select" name="user" mdui-select>
{%for user in get_od_user()%}
{%if user[1]!='添加网盘'%}
<option value="{{user[0]}}">{{user[1]}}</option>
{%endif%}
{%endfor%}
</select>
</div>
<div class="mdui-col-xs-4">
<label class="mdui-textfield-label">服务器文件/文件夹</label>
<input name="local" class="mdui-textfield-input" type="text" value="{%if local%}{{local}}{%else%}/{%endif%}"/>
</div>
</div>
<div class="mdui-col-xs-3">
<div class="mdui-textfield">
<label class="mdui-textfield-label">远程目录</label>
<input name="remote" class="mdui-textfield-input" type="text" value="{%if remote%}{{remote}}{%endif%}" />
</div>
</div>
<div class="mdui-col-xs-2" style="padding-top: 34px;">
<button type="submit" name="upload" value="1" class="mdui-btn mdui-btn-block mdui-color-green-600 mdui-ripple">
@ -40,7 +46,7 @@
</div>
<script>
{%if local%}
var source = new EventSource("{{url_for('admin.web_console',local=local,remote=remote,action=action)|safe}}");
var source = new EventSource("{{url_for('admin.web_console',local=local,remote=remote,action=action,user=user)|safe}}");
source.onmessage = function(event) {
if(event.data=='end'){
source.close();

@ -298,8 +298,8 @@
map.remove(id);
});
function upload_to_one(id,filename,remote_folder){
var source = new EventSource("{{url_for('admin.server_to_one')|safe}}?filename="+filename+"&remote_folder="+remote_folder);
function upload_to_one(id,filename,remote_folder,user){
var source = new EventSource("{{url_for('admin.server_to_one')|safe}}?filename="+filename+"&remote_folder="+remote_folder+"&user={{cur_user}}");
source.onmessage = function(event) {
if(event.data=='end'){
source.close();

@ -1,15 +1,25 @@
<div class="mdui-container-fluid">
<div class="mdui-toolbar nexmoe-item">
<a href="/">{{title}}</a>
{%if path%}
{%for idx,p in enumerate(path_list(path))%}
<i class="mdui-icon material-icons mdui-icon-dark" style="margin:0;">chevron_right</i>
{%if idx==len(path_list(path))-1%}
<a href="#">{{p}}</a>
{%else%}
<a href="{{url_for('.index',path='/'.join(path_list(path)[:idx+1]))}}">{{p}}</a>
<div class="mdui-appbar mdui-appbar-scroll-hide">
<div class="mdui-tab mdui-color-theme" mdui-tab>
{%for user in get_od_user()%}
<a href="{{user[2]}}" class="mdui-ripple mdui-ripple-white{%if cur_user==user[0]%} mdui-tab-active{%endif%}" id="{{user[0]}}">
<i class="mdui-icon material-icons">&#xe2bf;</i>
<label>{{user[1]}}</label>
</a>
{%endfor%}
</div>
<div class="mdui-toolbar nexmoe-item">
<a href="{{url_for('.index',path=cur_user+':/')}}">{{cur_user}}</a>
{%if path%}
{%for idx,p in enumerate(path_list(path))%}
<i class="mdui-icon material-icons mdui-icon-dark" style="margin:0;">chevron_right</i>
{%if idx==len(path_list(path))-1%}
<a href="#">{{p|replace(cur_user+':/','')|replace(cur_user+':','')}}</a>
{%else%}
<a href="{{url_for('.index',path='/'.join(path_list(path))[:idx+1])}}">{{p|replace(cur_user+':/','')|replace(cur_user+':','')}}</a>
{%endif%}
{%endfor%}
{%endif%}
{%endfor%}
{%endif%}
</div>
</div>
</div>

@ -20,9 +20,13 @@
<div class="mdui-col-sm-2 mdui-text-right">{{ macros.Arraw(name='文件类型',cur_type='type',sortby=sortby,order=order,path=path) }}</div>
<div class="mdui-col-sm-2 mdui-text-right">{{ macros.Arraw(name='大小',cur_type='size',sortby=sortby,order=order,path=path) }}</div>
</li>
{%if path!='/'%}
{%if path.split(':')[-1]!=''%}
<li class="mdui-list-item mdui-ripple">
<a href="{{url_for('.index',path='/'.join(path_list(path)[:-1]))}}">
{%if '/'.join(path_list(path)[:-1])==''%}
<a href="{{url_for('.index',path=cur_user+':/')|safe}}">
{%else%}
<a href="{{url_for('.index',path='/'.join(path_list(path)[:-1]))|safe}}">
{%endif%}
<div class="mdui-col-xs-12 mdui-col-sm-7">
<i class="mdui-icon material-icons">arrow_upward</i> 返回上一层
</div>
@ -46,10 +50,10 @@
</li>
{%else%}
<li class="mdui-list-item file mdui-ripple">
<a href="{{url_for('.index',path=path+'/'+data['name'])}}" target="_blank">
<a href="{{url_for('.index',path=path+'/'+data['name'])|safe}}" target="_blank">
{%if image_mode==1%}
{%if file_ico(data)=='image'%}
<img class="mdui-img-fluid" src="{{url_for('.show',fileid=data['id'])}}"/>
<img class="mdui-img-fluid" src="{{url_for('.show',fileid=data['id'],user=cur_user)}}"/>
{%else%}
<div class="mdui-col-xs-8 mdui-col-sm-5 mdui-text-truncate">
<i class="mdui-icon material-icons">{{file_ico(data)}}</i> {{data['name']}}

Loading…
Cancel
Save