Skip to content

Commit

Permalink
v1.2
Browse files Browse the repository at this point in the history
新增:
浏览器插件
可以从浏览页面捕获图片直接上传到云相册;
  • Loading branch information
Yooki-K committed Aug 31, 2022
1 parent fc73c4c commit 0319ddc
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 33 deletions.
5 changes: 2 additions & 3 deletions DataSQL/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ class User(db.Model):
user = db.Column(db.String(64), unique=True, nullable=False)
name = db.Column(db.String(64), nullable=False)
pwd = db.Column(db.String(64))
facesetid = db.Column(db.String(128))
avatar = db.Column(db.LargeBinary(length=65536)) # 二进制图片流 头像
# points = db.Column(db.Integer, default=0)
# space = db.Column(db.Integer, default=1024 * 1024 * 1024) # 内存初始1GB
Expand All @@ -21,15 +20,15 @@ def __repr__(self):

# dict(user),会先调用keys方法,这里重写,自定义获取返回的字段
def keys(self):
return ['id', 'user', 'name', 'pwd', 'facesetid']
return ['id', 'user', 'name', 'pwd']

# dict(user)获取完字段后,会取出对应字段的值,这里使用__getitem__,这里getattr(self, item)拿到值信息,item为key名
def __getitem__(self, item):
return getattr(self, item)

@staticmethod
def from_dict(u: dict):
return User(user=u['user'], id=u['id'], name=u['name'], facesetid=u['facesetid'])
return User(user=u['user'], id=u['id'], name=u['name'])


tb_album_img = db.Table('album_img',
Expand Down
119 changes: 96 additions & 23 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def sign_in():
action='signing in fails!!!', back=url_for('sign_in_page'))
session['User'] = result
if rem == 'on':
session.permanent = True # 设置session永久有效(7天内免登录)
session.permanent = True # 设置session永久有效
return redirect(url_for('index', userid=result['id'], tt=1))


Expand Down Expand Up @@ -202,8 +202,7 @@ def getUser():
'user': r.user,
'name': r.name,
'pwd': r.pwd,
'avatar': r.avatar,
'facesetid': r.facesetid
'avatar': r.avatar
}
if r.avatar is not None and len(r.avatar) != 0:
rr['avatar'] = ImgHandler.getBase64(r.avatar)
Expand Down Expand Up @@ -619,49 +618,123 @@ def clear_recycle():
return '请先登录'


@app.route('/addImageFromUrl', methods=['post', 'get'])
@app.route('/', methods=['GET', 'POST'])
def mainPage():
return redirect(url_for('sign_in_page'))


# 插件区

def checkCookie(request, session):
if 'XFYID' in request.cookies:
XFYID = request.cookies['XFYID']
else:
return False
if 'KEY' in request.cookies:
KEY = request.cookies['KEY']
else:
return False
username = aes_decrypt(XFYID, KEY)
r = session.query(User).filter(User.user == username).first()
if r is None:
return False
else:
return r


@app.route('/plug-in/addImageFromUrl', methods=['post'])
@cross_origin()
def addImageFromUrl():
if request.method == 'GET':
return ''
u = checkCookie(request, db.session)
if not u:
return '登录失败'
else:
hhh = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Connection': 'keep-alive',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36 Edg/93.0.961.38',
'User-Agent': request.headers['USER_AGENT'],
}
txt = request.data.decode()
txts = request.json.get('data')
data = []
txts = txt.split(',,,')
facesetid = txts.pop(0)
u = db.session.query(User).filter(facesetid == facesetid).first()
error = []
for x in txts: # todo 插件API
d = {}
if 'data:image' in x:
a = x.split('base64,')[1]
d['filename'] = a[:7]
d = {'filename': x['name']}
if 'data:image' in x['content']:
a = x['content'].split('base64,')[1]
d['stream'] = decode(a)
data.append(d)
if 'http' in x:
temp = x.split('/')[-1]
d['filename'] = re.findall('(.*?)\.', temp)[0]
r = requests.get(url=x, headers=hhh, timeout=10)
if 'http' in x['content']:
r = requests.get(url=x['content'], headers=hhh, timeout=5)
if '<!DOCTYPE html>' not in r.text:
d['stream'] = r.content
data.append(d)
else:
error.append(x['content'])
upload_img(db.session, u.user, data, 10, None, True)
return '成功'
if len(error) > 0:
return "以下链接上传失败: \n" + '\n'.join(error)
else:
return '上传成功'


@app.route('/', methods=['GET', 'POST'])
def mainPage():
return redirect(url_for('sign_in_page'))
# 登录 username -用户名 pwd -登录密码
@app.route('/plug-in/sign-in', methods=['post'])
def sign_in_():
user = request.form.get('username')
pwd = request.form.get('pwd')
result = db.session.query(User).filter(User.user == user).first()
if result is None:
return '该用户不存在'
if result.pwd != pwd:
return '密码错误'
session['User'] = result
resp = make_response('登陆成功')
aes_key = generate_random_str(16)
resp.set_cookie("XFYID", aes_encrypt(user, aes_key), max_age=3600 * 24 * 365)
resp.set_cookie("KEY", aes_key, max_age=3600 * 24 * 365)
return resp


# 获得用户个人信息
@app.route('/plug-in/getUser', methods=['POST'])
def getUser_():
r = checkCookie(request, db.session)
if not r:
return '登录失败'
rr = {
'user': r.user,
'name': r.name,
'avatar': r.avatar
}
if r.avatar is not None and len(r.avatar) != 0:
rr['avatar'] = ImgHandler.getBase64(r.avatar)
return jsonify(rr)


# 登出
@app.route('/plug-in/logout', methods=['get'])
def logout_():
resp = make_response('登出成功')
resp.delete_cookie('XFYID')
resp.delete_cookie('KEY')
return resp


@app.route('/plug-in/getAblumName', methods=['get'])
def getAblumName_():
u = checkCookie(request, db.session)
if not u:
return '登录失败'
r = db.session.query(Album.name).filter(Album.user == u.user).all()
r = [x[0] for x in r]
return json.dumps({'data': r})


if __name__ == '__main__':
delete_timeout(db.session)
# reset()
app.run(host='127.0.0.1', port=80)
# app.run(host='10.0.4.12', port=80)
pass
1 change: 0 additions & 1 deletion static/js/send.js
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,6 @@ function openRegisterModal(t){
console.log(data.avatar)
e.find('input[name=username]').val(data.user)
e.find('input[name=name]').val(data.name)
e.find('#facesetid').html(data.facesetid)
if(data.avatar){
$('#myAvatar').attr('src',data.avatar)
$('#nav-avatar').attr('src',data.avatar)
Expand Down
4 changes: 0 additions & 4 deletions templates/base/baseHtml.html
Original file line number Diff line number Diff line change
Expand Up @@ -501,10 +501,6 @@ <h4 class="modal-title">个人信息</h4>
<input type="text" class="form-control" name="name" value=""
autofocus="">
</div>
<div class="input-group margin-top-8x">
<span class="input-group-addon ">库ID</span>
<span class="form-control" id="facesetid"></span>
</div>
<button class="btn margin-top-8x" style="padding: 0 10px;max-height:30px;"
onclick="return check(this,2,'/operate/users/update')">保存
</button>
Expand Down
41 changes: 39 additions & 2 deletions utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
import urllib.parse
from hashlib import sha1
from hashlib import sha256
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
from io import BytesIO

import cv2
import numpy as np
from PIL import Image
Expand Down Expand Up @@ -99,7 +100,8 @@ class ImgHandler:
'ICO': b'\x00\x00\x01\x00\x01\x00\x20\x20',
'GIF': b'\x47\x49\x46',
'BMP': b'\x42\xd4D',
'TIFF': [b'\x4D\x4D', b'\x49\x49']
'TIFF': [b'\x4D\x4D', b'\x49\x49'],
'webp': b'RIFF'
}

@staticmethod
Expand Down Expand Up @@ -130,6 +132,41 @@ def getBase64(f_stream, t=None) -> [str, None]:
return None


def aes_encrypt(message, aes_key):
"""use AES to encrypt message,
:param message: 需要加密的内容
:param aes_key: 密钥
:return: encrypted_message密文
"""
mode = AES.MODE_ECB # 加密模式
if type(message) == str:
message = bytes(message, 'utf-8')
if type(aes_key) == str:
aes_key = bytes(aes_key, 'utf-8')
# aes_key, message必须为16的倍数
while len(aes_key) % 16 != 0:
aes_key += b' '
while len(message) % 16 != 0:
message += b' '
# 加密对象aes
aes = AES.new(key=aes_key, mode=mode)
encrypt_message = aes.encrypt(plaintext=message)
return b2a_hex(encrypt_message)


def aes_decrypt(encrypt_message, aes_key):
""" AES解密
:param encrypt_message: 密文
:param aes_key: 秘钥
:return: decrypt_text解密后内容
"""
aes_mode = AES.MODE_ECB # 加密模式
aes = AES.new(key=bytes(aes_key, 'utf-8'), mode=aes_mode)
decrypted_text = aes.decrypt(a2b_hex(encrypt_message))
decrypted_text = decrypted_text.rstrip() # 去空格
return decrypted_text.decode()


class Signature:
def __init__(self, accessKey, secretKey):
self.access_key = accessKey
Expand Down

0 comments on commit 0319ddc

Please sign in to comment.