mirror of https://github.com/IoTcat/PyOne.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
552 lines
20 KiB
552 lines
20 KiB
#-*- coding=utf-8 -*- |
|
from flask import url_for,request |
|
import hashlib |
|
import markdown |
|
from header import * |
|
|
|
################################################################################ |
|
###################################功能函数##################################### |
|
################################################################################ |
|
def md5(string): |
|
a=hashlib.md5() |
|
a.update(string.encode(encoding='utf-8')) |
|
return a.hexdigest() |
|
|
|
def GetTotal(path='{}:/'.format(GetConfig('default_pan'))): |
|
key='file_count:{}'.format(path) |
|
if redis_client.exists(key): |
|
return int(redis_client.get(key)) |
|
else: |
|
user,n_path=path.split(':') |
|
if n_path=='/': |
|
total=mon_db.items.find({'grandid':0,'user':user}).count() |
|
else: |
|
f=mon_db.items.find_one({'path':path}) |
|
pid=f['id'] |
|
total=mon_db.items.find({'parent':pid}).count() |
|
redis_client.set(key,total,300) |
|
return total |
|
|
|
|
|
# @cache.memoize(timeout=60*5) |
|
def FetchData(path='{}:/'.format(GetConfig('default_pan')),page=1,per_page=50,sortby='lastModtime',order='desc',action=None,dismiss=False,search_mode=False): |
|
balance=eval(GetConfig('balance')) |
|
if search_mode: |
|
show_secret=GetConfig('show_secret') |
|
query=mon_db.items.find({'name':re.compile(path)}) |
|
resp=[] |
|
data=query.limit(per_page).collation({"locale": "zh", 'numericOrdering':True})\ |
|
.sort([('order',ASCENDING)])\ |
|
.skip((page-1)*per_page) |
|
for d in data: |
|
if show_secret=='no': |
|
if d['type']=='folder': |
|
folder_name=d['path'] |
|
else: |
|
folder_name=d['path'].replace('/'+d['name'],'') |
|
_,has_password,_=has_item(folder_name,'.password') |
|
if has_password!=False: |
|
continue |
|
item={} |
|
item['name']=d['name'] |
|
item['id']=d['id'] |
|
item['lastModtime']=d['lastModtime'] |
|
item['size']=d['size'] |
|
item['type']=d['type'] |
|
item['path']=d['path'] |
|
if dismiss: |
|
if d['name'] not in ('README.md','README.txt','readme.md','readme.txt','.password','HEAD.md','HEAD.txt','head.md','head.txt'): |
|
resp.append(item) |
|
else: |
|
resp.append(item) |
|
total=len(resp) |
|
return resp,total |
|
path=urllib.unquote(path) |
|
resp=[] |
|
if sortby not in ['lastModtime','type','size','name']: |
|
sortby='lastModtime' |
|
if sortby=='size': |
|
sortby='size_order' |
|
if order=='desc': |
|
order=DESCENDING |
|
else: |
|
order=ASCENDING |
|
try: |
|
user,n_path=path.split(':') |
|
if n_path=='/': |
|
data=mon_db.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: |
|
item={} |
|
item['name']=d['name'] |
|
item['id']=d['id'] |
|
item['lastModtime']=d['lastModtime'] |
|
item['size']=d['size'] |
|
item['type']=d['type'] |
|
item['path']=d['path'] |
|
if dismiss: |
|
if d['name'] not in ('README.md','README.txt','readme.md','readme.txt','.password','HEAD.md','HEAD.txt','head.md','head.txt'): |
|
resp.append(item) |
|
else: |
|
resp.append(item) |
|
total=GetTotal(path) |
|
else: |
|
f=mon_db.items.find_one({'path':path}) |
|
pid=f['id'] |
|
if f['type']!='folder': |
|
if balance and action!='share': |
|
user,p=path.split(':') |
|
p2=p.replace('(','\(').replace(')','\)').replace('|','\|')\ |
|
.replace('*','\*').replace('.','\.').replace('?','\?')\ |
|
.replace('[','\[').replace(']','\]') |
|
files=mon_db.items.find({'path':re.compile(p2)}) |
|
key='balance:{}'.format(p) |
|
users=[] |
|
for file in files: |
|
suser=file['user'] |
|
if redis_client.hexists(key,suser): |
|
cnt=redis_client.hget(key,suser) |
|
if cnt is None: |
|
cnt=0 |
|
else: |
|
cnt=int(cnt) |
|
else: |
|
cnt=0 |
|
users.append([suser,cnt]) |
|
users.sort(key=lambda x:x[1]) |
|
ssuser=users[0][0] |
|
pp='{}:{}'.format(ssuser,p) |
|
redis_client.hincrby(key,ssuser,1) |
|
f=mon_db.items.find_one({'path':pp}) |
|
return f,'files' |
|
data=mon_db.items.find({'parent':pid}).collation({"locale": "zh", 'numericOrdering':True})\ |
|
.sort([('order',ASCENDING),(sortby,order)])\ |
|
.limit(per_page).skip((page-1)*per_page) |
|
for d in data: |
|
item={} |
|
item['name']=d['name'] |
|
item['id']=d['id'] |
|
item['lastModtime']=d['lastModtime'] |
|
item['size']=d['size'] |
|
item['type']=d['type'] |
|
item['path']=d['path'] |
|
if dismiss: |
|
if d['name'] not in ('README.md','README.txt','readme.md','readme.txt','.password','HEAD.md','HEAD.txt','head.md','head.txt'): |
|
resp.append(item) |
|
else: |
|
resp.append(item) |
|
total=GetTotal(path) |
|
except Exception as e: |
|
exestr=traceback.format_exc() |
|
resp=[] |
|
total=0 |
|
return resp,total |
|
|
|
# @cache.memoize(timeout=60*5) |
|
def _thunbnail(id,user): |
|
app_url=GetAppUrl(user) |
|
od_type=get_value('od_type',user) |
|
token=GetToken(user=user) |
|
headers={'Authorization':'bearer {}'.format(token),'Content-type':'application/json'} |
|
headers.update(default_headers) |
|
if od_type=='nocn' or od_type is None or od_type==False: |
|
url=app_url+'v1.0/me/drive/items/{}/thumbnails/0?select=large'.format(id) |
|
else: |
|
url=app_url+'_api/v2.0/me/drive/items/{}/thumbnails/0?select=large'.format(id) |
|
r=browser.get(url,headers=headers,verify=False) |
|
data=json.loads(r.content) |
|
if data.get('large').get('url'): |
|
# return data.get('large').get('url').replace('thumbnail','videotranscode').replace('&width=800&height=800','')+'&format=dash&track=audio&transcodeAhead=0&part=initsegment&quality=audhigh' |
|
return data.get('large').get('url') |
|
# return data.get('large').get('url').replace('thumbnail','videotranscode').replace('&width=800&height=800','')+'&format=dash&track=audio&transcodeAhead=0&part=initsegment&quality=audhigh' |
|
else: |
|
return False |
|
|
|
# @cache.memoize(timeout=60*5) |
|
def _getdownloadurl(id,user): |
|
app_url=GetAppUrl(user) |
|
od_type=get_value('od_type',user) |
|
token=GetToken(user=user) |
|
filename=GetName(id) |
|
ext=filename.split('.')[-1].lower() |
|
headers={'Authorization':'bearer {}'.format(token),'Content-type':'application/json'} |
|
headers.update(default_headers) |
|
if od_type=='nocn' or od_type is None or od_type==False: |
|
url=app_url+'v1.0/me/drive/items/'+id |
|
else: |
|
url=app_url+'_api/v2.0/me/drive/items/'+id |
|
r=browser.get(url,headers=headers,verify=False) |
|
data=json.loads(r.content) |
|
if data.get('@microsoft.graph.downloadUrl'): |
|
downloadUrl=data.get('@microsoft.graph.downloadUrl') |
|
elif data.get('@content.downloadUrl'): |
|
downloadUrl=data.get('@content.downloadUrl') |
|
else: |
|
ErrorLogger().print_r('Getting resource:{} {} error:{}'.format(id,filename,data.get('error').get('message'))) |
|
downloadUrl=data.get('error').get('message') |
|
# if ext in ['webm','avi','mpg', 'mpeg', 'rm', 'rmvb', 'mov', 'wmv', 'mkv', 'asf'] and od_type=='nocn' and 1==0: |
|
# play_url=_thunbnail(id,user) |
|
# play_url=play_url.replace('thumbnail','videomanifest').replace('&width=800&height=800','')+'&part=index&format=dash&useScf=True&pretranscode=0&transcodeahead=0' |
|
# # play_url=re.sub('inputFormat=.*?&','inputFormat=mp4&',play_url) |
|
# # downloadUrl=downloadUrl.replace('thumbnail','videomanifest').replace('&width=800&height=800','')+'&part=index&format=dash&useScf=True&pretranscode=0&transcodeahead=0' |
|
# else: |
|
play_url=downloadUrl |
|
return downloadUrl,play_url |
|
|
|
def GetDownloadUrl(id,user): |
|
key_='downloadurl:{}'.format(id) |
|
if redis_client.exists(key_): |
|
downloadUrl,play_url,ftime=redis_client.get(key_).split('####') |
|
if time.time()-int(ftime)>=600: |
|
# InfoLogger().print_r('{} downloadUrl expired!'.format(id)) |
|
downloadUrl,play_url=_getdownloadurl(id,user) |
|
ftime=int(time.time()) |
|
k='####'.join([downloadUrl,play_url,str(ftime)]) |
|
redis_client.set(key_,k) |
|
else: |
|
# InfoLogger().print_r('get {}\'s downloadUrl from cache'.format(id)) |
|
downloadUrl=downloadUrl |
|
play_url=play_url |
|
else: |
|
# InfoLogger().print_r('first time get downloadUrl from {}'.format(id)) |
|
downloadUrl,play_url=_getdownloadurl(id,user) |
|
ftime=int(time.time()) |
|
if not downloadUrl.startswith('http'): |
|
return downloadUrl,downloadUrl |
|
k='####'.join([downloadUrl,play_url,str(ftime)]) |
|
redis_client.set(key_,k) |
|
return downloadUrl,play_url |
|
|
|
|
|
|
|
# @cache.memoize(timeout=60*5) |
|
def GetReadMe(path): |
|
# README |
|
ext='Markdown' |
|
readme,_,i=has_item(path,'README.md') |
|
if readme==False: |
|
readme,_,i=has_item(path,'readme.md') |
|
if readme==False: |
|
ext='Text' |
|
readme,_,i=has_item(path,'readme.txt') |
|
if readme==False: |
|
ext='Text' |
|
readme,_,i=has_item(path,'README.txt') |
|
if readme!=False: |
|
readme=markdown.markdown(readme, extensions=['tables','codehilite']) |
|
return readme,ext |
|
|
|
|
|
# @cache.memoize(timeout=60*5) |
|
def GetHead(path): |
|
# README |
|
ext='Markdown' |
|
head,_,i=has_item(path,'HEAD.md') |
|
if head==False: |
|
head,_,i=has_item(path,'head.md') |
|
if head==False: |
|
ext='Text' |
|
head,_,i=has_item(path,'head.txt') |
|
if head==False: |
|
ext='Text' |
|
head,_,i=has_item(path,'HEAD.txt') |
|
if head!=False: |
|
head=markdown.markdown(head, extensions=['tables','codehilite']) |
|
return head,ext |
|
|
|
|
|
def CanEdit(filename): |
|
ext=filename.split('.')[-1].lower() |
|
if ext in ["html","htm","php","css","go","java","js","json","txt","sh","md",".password"]: |
|
return True |
|
else: |
|
return False |
|
|
|
def CodeType(ext): |
|
code_type={} |
|
code_type['html'] = 'html' |
|
code_type['htm'] = 'html' |
|
code_type['php'] = 'php' |
|
code_type['py'] = 'python' |
|
code_type['css'] = 'css' |
|
code_type['go'] = 'golang' |
|
code_type['java'] = 'java' |
|
code_type['js'] = 'javascript' |
|
code_type['json'] = 'json' |
|
code_type['txt'] = 'Text' |
|
code_type['sh'] = 'sh' |
|
code_type['md'] = 'Markdown' |
|
if code_type.get(ext.lower()): |
|
return code_type.get(ext.lower()) |
|
else: |
|
return ext |
|
|
|
def file_ico(item): |
|
try: |
|
ext = item['name'].split('.')[-1].lower() |
|
if ext in ['bmp','jpg','jpeg','png','gif']: |
|
return "image" |
|
|
|
if ext in ['mp4','mkv','webm','avi','mpg', 'mpeg', 'rm', 'rmvb', 'mov', 'wmv', 'mkv', 'asf']: |
|
return "ondemand_video" |
|
|
|
if ext in ['ogg','mp3','wav']: |
|
return "audiotrack" |
|
|
|
return "insert_drive_file" |
|
except: |
|
return "insert_drive_file" |
|
|
|
def _remote_content(fileid,user): |
|
kc='{}:content'.format(fileid) |
|
if redis_client.exists(kc): |
|
content=unicode(redis_client.get(kc), errors='ignore') |
|
return content |
|
else: |
|
downloadUrl,play_url=GetDownloadUrl(fileid,user) |
|
if downloadUrl: |
|
r=browser.get(downloadUrl,verify=False) |
|
# r.encoding='utf-8' |
|
if r.encoding=='ISO-8859-1': |
|
content=r.content |
|
else: |
|
content=r.text |
|
redis_client.set(kc,content) |
|
return content |
|
else: |
|
return False |
|
|
|
# @cache.memoize(timeout=60) |
|
def has_item(path,name): |
|
if mon_db.items.count()==0: |
|
return False,False,False |
|
if len(path.split('/'))==1: |
|
path=path+'/' |
|
key='has_item$#$#$#$#{}$#$#$#$#{}'.format(path,name) |
|
# if False: |
|
if redis_client.exists(key): |
|
values=redis_client.get(key) |
|
item,fid,cur=values.split('########') |
|
if item=='False': |
|
item=False |
|
if cur=='False': |
|
cur=False |
|
else: |
|
cur=True |
|
if fid=='False': |
|
fid=False |
|
return item,fid,cur |
|
else: |
|
item=False |
|
fid=False |
|
dz=False |
|
cur=False |
|
if name=='.password': |
|
dz=True |
|
try: |
|
user,n_path=path.split(':') |
|
if n_path=='/': |
|
if mon_db.items.find_one({'grandid':0,'name':name,'user':user}): |
|
fid=mon_db.items.find_one({'grandid':0,'name':name,'user':user})['id'] |
|
item=_remote_content(fid,user).strip() |
|
else: |
|
route=n_path.split('/') |
|
if name=='.password': |
|
for idx,r in enumerate(route): |
|
if r=='': |
|
data=mon_db.items.find_one({'name':name,'user':user,'grandid':0}) |
|
else: |
|
p=user+':'+'/'.join(route[:idx+1]) |
|
f=mon_db.items.find_one({'path':p}) |
|
pid=f['id'] |
|
data=mon_db.items.find_one({'name':name,'parent':pid}) |
|
if data: |
|
fid=data['id'] |
|
item=_remote_content(fid,user).strip() |
|
if idx==len(route)-1: |
|
cur=True |
|
else: |
|
f=mon_db.items.find_one({'path':path}) |
|
pid=f['id'] |
|
data=mon_db.items.find_one({'name':name,'parent':pid}) |
|
if data: |
|
fid=data['id'] |
|
item=_remote_content(fid,user).strip() |
|
except Exception as e: |
|
exstr = traceback.format_exc() |
|
ErrorLogger().print_r(exstr) |
|
item=False |
|
redis_client.set(key,'{}########{}########{}'.format(item,fid,cur)) |
|
return item,fid,cur |
|
|
|
|
|
|
|
def has_verify(path): |
|
verify=False |
|
md5_p=md5(path) |
|
passwd,fid,cur=has_item(path,'.password') |
|
if fid and cur: |
|
vp=request.cookies.get(md5_p) |
|
if passwd==vp: |
|
verify=True |
|
else: |
|
check_path=path |
|
while 1: |
|
passwd,fid,cur=has_item(check_path,'.password') |
|
md5_p=md5(check_path) |
|
vp=request.cookies.get(md5_p) |
|
if passwd==vp: |
|
verify=True |
|
if check_path.split('/')[-1]!='': |
|
tmp_path='/'.join(check_path.split('/')[:-1]) |
|
if '/' not in tmp_path: |
|
check_path=tmp_path+'/' |
|
else: |
|
check_path=tmp_path |
|
else: |
|
break |
|
return verify |
|
|
|
def path_list(path): |
|
try: |
|
path=urllib.unquote(path) |
|
if path.split(':',1)=='': |
|
plist=[path+'/'] |
|
else: |
|
user,n_path=path.split(':',1) |
|
if n_path.startswith('/'): |
|
n_path=n_path[1:] |
|
if n_path.endswith('/'): |
|
n_path=n_path[:-1] |
|
plist=n_path.split('/') |
|
if len(plist)==1: |
|
plist=['',plist[0]] |
|
plist=list(set(['{}:/{}'.format(user,i) for i in plist])) |
|
return plist |
|
except: |
|
return [] |
|
|
|
def breadCrumb(path): |
|
if path.endswith('/'): |
|
path=path[:-1] |
|
plist=path.split('/') |
|
#name:显示名称;pt:路径; |
|
for idx,p in enumerate(plist): |
|
if idx==0: |
|
name=p.split(':')[0] |
|
pt='/'+plist[0] |
|
last=False |
|
elif idx==len(plist)-1: |
|
name=p |
|
pt='/'+'/'.join(plist[:idx+1]) |
|
last=True |
|
else: |
|
name=p |
|
pt='/'+'/'.join(plist[:idx+1]) |
|
last=False |
|
yield name,pt,last |
|
|
|
|
|
|
|
|
|
|
|
def get_od_user(admin=False): |
|
balance=eval(GetConfig('balance')) |
|
config_path=os.path.join(config_dir,'self_config.py') |
|
with open(config_path,'r') as f: |
|
text=f.read() |
|
users=GetConfig('od_users') |
|
ret=[] |
|
for user,value in users.items(): |
|
if value.get('client_id')!='': |
|
#userid,username,endpoint,sharepath,order |
|
if balance and not admin: |
|
if user==GetConfig('default_pan'): |
|
ret.append( |
|
( |
|
user, |
|
value.get('other_name'), |
|
'/{}:'.format(user), |
|
value.get('share_path'), |
|
value.get('order') |
|
) |
|
) |
|
else: |
|
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 |
|
|
|
|
|
def GetCookie(key,default): |
|
value=request.args.get(key) |
|
if value is None: |
|
value=request.cookies.get(key) |
|
if value==None or value=='None': |
|
value=default |
|
if key=='image_mode': |
|
value=int(value) |
|
return value |
|
|
|
|
|
def GetSubDirectory(current_path): |
|
if (not current_path.endswith(':/')) and current_path.endswith('/'): |
|
current_path=current_path[:-1] |
|
retdata=[] |
|
if current_path.endswith(':/'): |
|
user=current_path.split(':')[0] |
|
subfolders=mon_db.items.find({'user':user,'grandid':0,'type':'folder'}) |
|
for f in subfolders: |
|
info={} |
|
info['id']=f['id'] |
|
info['name']=f['name'] |
|
info['path']=f['path'] |
|
retdata.append(info) |
|
return retdata |
|
folder=mon_db.items.find_one({'path':current_path}) |
|
if folder is None: |
|
return [] |
|
pid=folder['id'] |
|
subfolders=mon_db.items.find({'parent':pid,'type':'folder'}) |
|
for f in subfolders: |
|
info={} |
|
info['id']=f['id'] |
|
info['name']=f['name'] |
|
info['path']=f['path'] |
|
retdata.append(info) |
|
return retdata |
|
|
|
|
|
def GetTreeList(user): |
|
sp=' ' |
|
treelists=[] |
|
treelists.append({'path':'/','grandid':0,'split':''}) |
|
folders=mon_db.items.find({'user':user,'type':'folder'}) |
|
for folder in folders: |
|
info={} |
|
info['path']=folder['path'] |
|
info['grandid']=folder['grandid']+1 |
|
info['split']=sp*(folder['grandid']+1) |
|
treelists.append(info) |
|
treelists.sort(key=lambda x:x['grandid']) |
|
return treelists |
|
|
|
|
|
|