Skip to content

Commit 16c65da

Browse files
colorful3pedro
authored andcommitted
Feature notify (#18)
* feat: 添加诗词插件
1 parent 8dd2bad commit 16c65da

20 files changed

Lines changed: 361 additions & 36 deletions

Pipfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ cymysql = "==0.9.1"
1111
flask-cors = "==2.1.0"
1212
requests = "==2.18.4"
1313
pipfile = "*"
14-
lin-cms = "==0.1.1a3"
14+
lin-cms = "==0.1.1a2"
15+
"oss2" = "*"
1516

1617
[dev-packages]
1718
pytest = "*"

app/api/v1/book.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
:copyright: © 2019 by the Lin team.
55
:license: MIT, see LICENSE for more details.
66
"""
7-
from lin import db, route_meta, group_required
7+
from lin import db, route_meta, group_required, login_required
8+
from lin.notify import Notify
89
from lin.redprint import Redprint
910
from flask import jsonify
1011
from lin.exception import NotFound, ParameterException, Success
@@ -16,7 +17,11 @@
1617
book_api = Redprint('book')
1718

1819

20+
# 注意:如果Notify添加的视图函数,没有添加任何视图函数,那么不可识别用户身份
21+
# 这与真实的情况是一致的,因为一般的情况下,重要的接口需要被保护,重要的消息才需要推送
1922
@book_api.route('/<id>', methods=['GET'])
23+
@login_required
24+
@Notify(template='{user.nickname}查询了一本图书', event='queryBook')
2025
def get_book(id):
2126
book = Book.query.filter_by(id=id).first() # 通过Book模型在数据库中查询id=`id`的书籍
2227
if book is None:
@@ -25,8 +30,10 @@ def get_book(id):
2530

2631

2732
@book_api.route('/', methods=['GET'])
33+
@login_required
34+
@Notify(template='{user.nickname}查询了所有图书', event='queryBooks')
2835
def get_books():
29-
books = Book.query.filter_by(delete_time=None).all()
36+
books = Book.query.filter_by(soft=True).all()
3037
if books is None or len(books) < 1:
3138
raise NotFound(msg='没有找到相关书籍')
3239
return jsonify(books)

app/config/setting.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,7 @@
1414

1515
# 插件模块暂时没有开启,以下配置可忽略
1616
# plugin config写在字典里面
17-
BP_URL_PREFIX = '/plugin'
18-
PLUGIN_PATH = {}
17+
PLUGIN_PATH = {
18+
'oss': {'path': 'app.plugins.oss', 'enable': True, 'upload_folder': 'app/static'},
19+
'poem': {'path': 'app.plugins.poem', 'enable': True, 'limit': 5},
20+
}

app/plugins/.gitkeep

Whitespace-only changes.

app/plugins/oss/app/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from .controller import api
2+
from .model import Image

app/plugins/oss/app/controller.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
from flask import jsonify, request
2+
import os
3+
from lin.exception import Success, ParameterException, Failed
4+
from .oss import upload_image_bytes
5+
from .model import Image
6+
from .enums import LocalOrCloud
7+
from lin.db import db
8+
from lin.redprint import Redprint
9+
from lin.core import lin_config
10+
11+
api = Redprint('oss')
12+
13+
14+
@api.route('/upload_to_local', methods=['POST'])
15+
def upload():
16+
image = request.files.get('image', None)
17+
if not image:
18+
raise ParameterException(msg='没有找到图片')
19+
if image and allowed_file(image.filename):
20+
path = os.path.join(lin_config.get_config('oss.upload_folder'), image.filename)
21+
image.save(path)
22+
else:
23+
raise ParameterException(msg='图片类型不允许或图片key不合法')
24+
return Success()
25+
26+
27+
@api.route('/upload_to_ali', methods=['POST'])
28+
def upload_to_ali():
29+
image = request.files.get('image', None)
30+
if not image:
31+
raise ParameterException(msg='没有找到图片')
32+
if image and allowed_file(image.filename):
33+
url = upload_image_bytes(image.filename, image)
34+
if url:
35+
res = {
36+
'url': url
37+
}
38+
with db.auto_commit():
39+
exist = Image.get(url=url)
40+
if not exist:
41+
data = {
42+
'from': LocalOrCloud.CLOUD.value,
43+
'url': url
44+
}
45+
one = Image.create(**data)
46+
db.session.flush()
47+
res['id'] = one.id
48+
else:
49+
res['id'] = exist.id
50+
return jsonify(res)
51+
return Failed(msg='上传图片失败,请检查图片路径')
52+
53+
54+
@api.route('/upload_multiple', methods=['POST'])
55+
def upload_multiple_to_ali():
56+
imgs = []
57+
for item in request.files:
58+
img = request.files.get(item, None)
59+
if not img:
60+
raise ParameterException(msg='没接收到图片,请检查图片路径')
61+
if img and allowed_file(img.filename):
62+
url = upload_image_bytes(img.filename, img)
63+
if url:
64+
# 每上传成功一次图片需记录到数据库
65+
with db.auto_commit():
66+
exist = Image.get(url=url)
67+
if not exist:
68+
data = {
69+
'from': LocalOrCloud.CLOUD.value,
70+
'url': url
71+
}
72+
res = Image.create(**data)
73+
db.session.flush()
74+
imgs.append({
75+
'key': item,
76+
'url': url,
77+
'id': res.id
78+
})
79+
else:
80+
imgs.append({
81+
'key': item,
82+
'url': url,
83+
'id': exist.id
84+
})
85+
return jsonify(imgs)
86+
87+
88+
def allowed_file(filename):
89+
return '.' in filename and \
90+
filename.rsplit('.', 1)[1] in lin_config.get_config('oss.allowed_extensions', [])

app/plugins/oss/app/enums.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from enum import Enum
2+
3+
4+
# 图片保存在本地还是云端
5+
# 建议云端
6+
class LocalOrCloud(Enum):
7+
LOCAL = 1
8+
CLOUD = 2

app/plugins/oss/app/model.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from lin.interface import BaseCrud
2+
from sqlalchemy import Column, Integer, String, FetchedValue
3+
4+
5+
class Image(BaseCrud):
6+
__tablename__ = 'image'
7+
8+
id = Column(Integer, primary_key=True)
9+
url = Column(String(255), nullable=False)
10+
_from = Column('from', Integer, nullable=False, server_default=FetchedValue())

app/plugins/oss/app/oss.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import oss2
2+
3+
from lin.util import get_random_str
4+
from lin.core import lin_config
5+
6+
7+
def upload_image_bytes(name: str, data: bytes):
8+
access_key_id = lin_config.get_config('oss.access_key_id')
9+
access_key_secret = lin_config.get_config('oss.access_key_secret')
10+
auth = oss2.Auth(access_key_id, access_key_secret)
11+
bucket = oss2.Bucket(auth, lin_config.get_config('oss.endpoint'), lin_config.get_config('oss.bucket_name'))
12+
suffix = name.split('.')[-1]
13+
rand_name = get_random_str(15) + '.' + suffix
14+
res = bucket.put_object(rand_name, data)
15+
if res.resp.status == 200:
16+
return res.resp.response.url
17+
return None

app/plugins/oss/config.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
access_key_id = 'not complete'
2+
access_key_secret = 'not complete'
3+
endpoint = 'http://oss-cn-shenzhen.aliyuncs.com'
4+
bucket_name = 'not complete'
5+
6+
upload_folder = 'app'
7+
allowed_extensions = ['jpg', 'gif', 'png', 'bmp']

0 commit comments

Comments
 (0)