#-*- coding=utf-8 -*- from flask import Blueprint,redirect,url_for,request,render_template,flash,session,jsonify,Response,make_response from flask_sqlalchemy import Pagination from function import * from config import * from run import FetchData,path_list,GetName,CodeType,_remote_content,rd,has_item,AddResource import os import io import re import subprocess import random import urllib from shelljob import proc import eventlet eventlet.monkey_patch() admin = Blueprint('admin', __name__,url_prefix='/admin') ############功能函数 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) config_path=os.path.join(config_dir,'config.py') with open(config_path,'r') as f: old_text=f.read() with open(config_path,'w') as f: 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: 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 session.get('login') is None: #and request.endpoint!='admin.install' return redirect(url_for('admin.login')) ########web console @admin.route('/web_console') def web_console(): g = proc.Group() action=request.args.get('action') allow_action=['UpdateFile','UploadDir','Upload'] if action not in allow_action: return make_response('error') if action in ['UploadDir','Upload']: local=urllib.unquote(request.args.get('local')) remote=urllib.unquote(request.args.get('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': 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) def read_process(): while g.is_pending(): lines = g.readlines() for proc, line in lines: yield "data:" + line + "\n\n" yield "data:end\n\n" return Response(read_process(), mimetype= 'text/event-stream') ########admin @admin.route('/',methods=['GET','POST']) @admin.route('/setting',methods=['GET','POST']) def setting(): if request.method=='POST': title=request.form.get('title','PyOne') 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','') password1=request.form.get('password1') password2=request.form.get('password2') new_password=password if ((password1 is not None and password2 is None) or (password1 is None and password2 is not None)): flash(u'请输入新密码或者二次确认新密码') elif password1 is not None and password2 is not None and password1!=password2: flash(u'两次输入密码不相同') elif password1 is not None and password2 is not None and password1==password2 and password1!='': new_password=password1 set('title',title) set('downloadUrl_timeout',downloadUrl_timeout) 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') @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): flash('本地目录/文件不存在') return redirect(url_for('admin.upload')) if os.path.isfile(local): action='Upload' else: action='UploadDir' return render_template('admin/upload.html',remote=remote,local=local,action=action,user=user) return render_template('admin/upload.html') @admin.route('/cache',methods=["POST","GET"]) def cache(): if request.method=='POST': type=request.form.get('type') return render_template('admin/cache.html',type=type,action='UpdateFile') return render_template('admin/cache.html') @admin.route('/manage',methods=["POST","GET"]) def manage(): if request.method=='POST': pass 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') order=request.args.get('order') if sortby: sortby=request.args.get('sortby') else: sortby=request.cookies.get('admin_sortby') if request.cookies.get('admin_sortby') is not None else 'lastModtime' sortby=sortby if order: order=request.args.get('order') else: order=request.cookies.get('admin_order') if request.cookies.get('admin_order') is not None else 'desc' 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) 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 @admin.route('/edit',methods=["GET","POST"]) 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(user=user) app_url=GetAppUrl() headers={'Authorization':'bearer {}'.format(token)} url=app_url+'v1.0/me/drive/items/{}/content'.format(fileid) try: r=requests.put(url,headers=headers,data=content,timeout=10) data=json.loads(r.content) if data.get('id'): info['status']=0 info['msg']='修改成功' rd.delete('{}:content'.format(fileid)) file=items.find_one({'id':fileid}) name=file['name'] 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: info['status']=0 info['msg']=data.get('error').get('message') except Exception as e: print e info['status']=0 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,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(): 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(): md5=request.form.get('fileMd5') fileName=request.form.get('name').encode('utf-8') chunk=request.form.get('chunk',0,type=int) filename = u'./upload/{}-{}'.format(fileName, chunk) if os.path.exists(filename): exists=True else: exists=False return jsonify({'ifExist':exists}) @admin.route('/mergeChunks', methods=['POST']) def mergeChunks(): fileName=request.form.get('fileName').encode('utf-8') md5=request.form.get('fileMd5') chunk = 0 # 分片序号 with open(u'./upload/{}'.format(fileName), 'wb') as target_file: # 创建新文件 while True: try: filename = u'./upload/{}-{}'.format(fileName, chunk) source_file = open(filename, 'rb') # 按序打开每个分片 target_file.write(source_file.read()) # 读取分片内容写入新文件 source_file.close() except IOError as msg: break chunk += 1 os.remove(filename) # 删除该分片,节约空间 return jsonify({'upload':True}) @admin.route('/recv_upload', methods=['POST']) def recv_upload(): # 接收前端上传的一个分片 md5=request.form.get('fileMd5') name=request.form.get('name').encode('utf-8') chunk_id=request.form.get('chunk',0,type=int) filename = '{}-{}'.format(name,chunk_id) upload_file = request.files['file'] upload_file.save(u'./upload/{}'.format(filename)) return jsonify({'upload_part':True}) @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,user) def read_status(): while 1: try: msg=_upload_session.next()['status'] yield "data:" + msg + "\n\n" except Exception as e: msg='end' yield "data:" + msg + "\n\n" os.remove(filepath) break return Response(read_status(), mimetype= 'text/event-stream') ###本地上传文件只onedrive,通过服务器中转 @admin.route('/setFile',methods=["GET","POST"]) @admin.route('/setFile/',methods=["GET","POST"]) 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 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(user=user) app_url=GetAppUrl() headers={'Authorization':'bearer {}'.format(token)} url=app_url+'v1.0/me/drive/items/root:{}:/content'.format(remote_file) try: r=requests.put(url,headers=headers,data=content,timeout=10) data=json.loads(r.content) if data.get('id'): AddResource(data,user) info['status']=0 info['msg']='添加成功' key='has_item$#$#$#$#{}$#$#$#$#{}'.format(path,filename) rd.delete(key) else: info['status']=0 info['msg']=data.get('error').get('message') except Exception as e: info['status']=0 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,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('##') infos={} infos['status']=1 infos['delete']=0 infos['fail']=0 for id in ids: file=items.find_one({'id':id}) name=file['name'] # path=file['path'].replace('/'+name,'').replace(name,'') if file['parent']=='': 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) kc='{}:content'.format(id) rd.delete(kc) status=DeleteRemoteFile(id,user) if status: infos['delete']+=1 else: infos['fail']+=1 return jsonify(infos) @admin.route('/add_folder',methods=['POST']) def AddFolder(): folder_name=request.form.get('folder_name') 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,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,user) return jsonify({'result':result}) @admin.route('/login',methods=["POST","GET"]) def login(): if request.method=='POST': password1=request.form.get('password') if password1==password: session['login']='true' return redirect(url_for('admin.setting')) else: return render_template('admin/login.html') return render_template('admin/login.html') @admin.route('/logout',methods=['GET','POST']) def logout(): session.pop('login',None) return redirect('/') @admin.route('/reload',methods=['GET','POST']) def reload(): cmd='supervisorctl -c {} restart pyone'.format(os.path.join(config_dir,'supervisord.conf')) subprocess.Popen(cmd,shell=True) flash('正在重启网站...如果更改了分享目录,请更新缓存') return redirect(url_for('admin.setting')) ###########################################安装 @admin.route('/install',methods=['POST','GET']) def install(): 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,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,cur_user=user) else: client_secret=request.form.get('client_secret') client_id=request.form.get('client_id') code=request.form.get('code') redirect_uri='https://auth.3pp.me' #授权 headers['Content-Type']='application/x-www-form-urlencoded' data=AuthData.format(client_id=client_id,redirect_uri=urllib.quote(redirect_uri),client_secret=client_secret,code=code) url=OAuthUrl 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'.format(user)),'w') as f: json.dump(Atoken,f,ensure_ascii=False) refresh_token=Atoken.get('refresh_token') 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('

授权成功!点击进入首页
请在后台另开一个ssh窗口,运行:
python function.py UpdateFile
进行更新数据操作

') else: return jsonify(Atoken) 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