添加api应用、优化代码

This commit is contained in:
yangjian 2020-05-16 21:27:00 +08:00
parent 91e0615cce
commit a88417905d
18 changed files with 1119 additions and 125 deletions

View File

@ -1,5 +1,13 @@
## 版本更新记录
### v0.5.2
- 添加Chrome内核浏览器扩展
- 添加API访问接口
- 优化配置路径;
- 增强代码安全性;
- 优化个人中心图片、文档模板的默认排序;
### v0.5.1 2020-05-08
- 优化个人中心交互体验;

View File

@ -1,10 +0,0 @@
from loguru import logger
from django.conf import settings
import os
LOG_DIR = os.path.join(settings.BASE_DIR,'log')
if os.path.exists(LOG_DIR) is False:
os.makedirs(LOG_DIR)
logger.add(os.path.join(LOG_DIR,'{time}.log'),rotation='1 days',retention='30 days',encoding='utf-8')

View File

@ -13,6 +13,7 @@ https://docs.djangoproject.com/en/2.1/ref/settings/
import os
from configparser import ConfigParser
from loguru import logger
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@ -22,6 +23,13 @@ CONFIG_DIR = os.path.join(BASE_DIR, 'config')
CONFIG = ConfigParser()
CONFIG.read(os.path.join(CONFIG_DIR,'config.ini'),encoding='utf-8')
# 日志文件配置
LOG_DIR = os.path.join(BASE_DIR,'log')
if os.path.exists(LOG_DIR) is False:
os.makedirs(LOG_DIR)
logger.add(os.path.join(LOG_DIR,'error.log'),rotation='1 days',retention='30 days',encoding='utf-8')
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
@ -32,11 +40,10 @@ SECRET_KEY = '5&71mt9@^58zdg*_!t(x6g14q*@84d%ptr%%s6e0l50zs0we3d'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = CONFIG.getboolean('site','debug')
VERSIONS = '0.5.1'
VERSIONS = '0.5.2'
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
@ -50,6 +57,7 @@ INSTALLED_APPS = [
'app_doc',
'app_api',
'django.contrib.sitemaps',
'rest_framework',
]
MIDDLEWARE = [
@ -80,6 +88,10 @@ TEMPLATES = [
'django.contrib.messages.context_processors.messages',
'app_admin.context_processors.sys_setting', # 自定义系统设置上下文渲染
],
'libraries': { # 自定义的模板标签
'doc_filter' : 'app_doc.templatetags.doc_filter',
'project_filter' : 'app_doc.templatetags.project_filter',
},
},
},
]
@ -168,3 +180,15 @@ MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10
}
# Chromium路径
try:
CHROMIUM_DIR = CONFIG['chromium']['path']
CHROMIUM_PATH = CHROMIUM_DIR
# CHROMIUM_PATH = os.path.join(CONFIG_DIR,CHROMIUM_DIR) # Windows便携版本使用config下的路径
except:
CHROMIUM_PATH = None

View File

@ -27,6 +27,7 @@ urlpatterns = [
path('',include('app_doc.urls')), # doc应用
path('user/',include('app_admin.urls'),), # admin应用
path('api/',include('app_api.urls')), # API应用
path('api_app/',include('app_api.urls_app')), # App的API接口
re_path('^static/(?P<path>.*)$',serve,{'document_root':settings.STATIC_ROOT}),# 静态文件
re_path('^media/(?P<path>.*)$',serve,{'document_root':settings.MEDIA_ROOT}),# 媒体文件
path('sitemap.xml', views.index, {'sitemaps': sitemaps,'template_name':'sitemap/sitemap-index.xml'},name='sitemap',), # 站点地图索引

View File

@ -4,7 +4,14 @@
### 介绍
`MrDoc`是基于`Python`开发的在线文档系统,适合作为个人和小型团队的文档、知识和笔记管理工具。
`MrDoc`是基于`Python`开发的在线文档系统适合作为个人和小型团队的文档、知识和笔记管理工具。致力于成为全平台Web端、桌面端、移动端的私有化在线文档部署方案。
目前涵盖:
- Web端
- Chrome扩展
- App端开发中
- Windows、Mac、Linux桌面端开发中
### 开源地址
@ -140,6 +147,8 @@ python manage.py runserver
## 赞赏项目
如果MrDoc对你有所帮助欢迎给予开发者赞赏助力项目更好发展。
开源不易需要鼓励如果MrDoc觅道文档对你有所帮助请给予一个`Star`。
欢迎给予开发者赞赏,助力项目更好发展。
![](./captrue/mrdoc-zan.png)

View File

@ -29,8 +29,6 @@ def check_code(request):
request.session["CheckCode"] = code
return HttpResponse(stream.getvalue())
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("生成验证码图片异常")
return HttpResponse("请求异常:{}".format(repr(e)))
@ -63,8 +61,6 @@ def log_in(request):
errormsg = '用户名或密码错误!'
return render(request, 'login.html', locals())
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("登录异常")
return HttpResponse('请求出错')
@ -150,8 +146,6 @@ def log_out(request):
try:
logout(request)
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("注销异常")
return redirect(request.META['HTTP_REFERER'])
@ -180,8 +174,6 @@ def forget_pwd(request):
errormsg = "验证码已过期"
return render(request, 'forget_pwd.html', locals())
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("修改密码异常")
errormsg = "验证码错误"
return render(request,'forget_pwd.html',locals())

52
app_api/auth_app.py Normal file
View File

@ -0,0 +1,52 @@
# coding:utf-8
# @文件: auth.py
# @创建者:州的先生
# #日期2020/5/11
# 博客地址zmister.com
from django.contrib.auth.models import User
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from app_api.models import *
class AppAuth(BaseAuthentication):
'''自定义认证类'''
def authenticate(self, request):
token = request.query_params.get('token')
# print(token)
if token:
# 如果请求url中携带有token参数
user_obj = AppUserToken.objects.filter(token=token).first()
if user_obj:
# print("ok")
# token 是有效的,返回一个元组
return user_obj.user, token # request.user, request.auth
else:
# raise AuthenticationFailed('无效的token')
return None
else:
# raise AuthenticationFailed('请求的URL中必须携带token参数')
return None
class AppMustAuth(BaseAuthentication):
'''自定义认证类'''
def authenticate(self, request):
token = request.query_params.get('token')
# print(token)
if token:
# 如果请求url中携带有token参数
user_obj = AppUserToken.objects.filter(token=token).first()
if user_obj:
# print("ok")
# token 是有效的,返回一个元组
return user_obj.user, token # request.user, request.auth
else:
raise AuthenticationFailed('无效的token')
# return None
else:
raise AuthenticationFailed('请求的URL中必须携带token参数')
# return None

View File

@ -0,0 +1,28 @@
# Generated by Django 2.2.12 on 2020-05-11 20:56
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('app_api', '0002_auto_20200322_0929'),
]
operations = [
migrations.CreateModel(
name='AppUserToken',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('token', models.CharField(max_length=250, unique=True, verbose_name='token值')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'App用户Token',
'verbose_name_plural': 'App用户Token',
},
),
]

View File

@ -1,7 +1,7 @@
from django.db import models
from django.contrib.auth.models import User
# Token模型
# Token模型 - 用于浏览器扩展
class UserToken(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
token = models.CharField(verbose_name="token值",max_length=250,unique=True)
@ -12,3 +12,15 @@ class UserToken(models.Model):
class Meta:
verbose_name = '用户Token'
verbose_name_plural = verbose_name
# AppToken模型 - 用于桌面、移动等各类 APP 应用
class AppUserToken(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
token = models.CharField(verbose_name="token值", max_length=250, unique=True)
def __str__(self):
return self.user
class Meta:
verbose_name = 'App用户Token'
verbose_name_plural = verbose_name

View File

@ -0,0 +1,31 @@
# coding:utf-8
# @文件: permissions.py
# @创建者:州的先生
# #日期2020/5/11
# 博客地址zmister.com
from rest_framework.permissions import BasePermission,SAFE_METHODS
class AppPermission(BasePermission):
message = '只有VIP才能访问'
def has_permission(self, request, view):
# vip才有访问权限
# request.user:当前经过认证的用户对象
# 如果没有认证 request.user就是匿名用户
if not request.auth:
# 认证没有通过
return False
if request.user.vip:
return True
else:
return False
def has_object_permission(self, request, view, obj):
if request.method in SAFE_METHODS:
return True
# 示例必须要有一个名为`owner`的属性
return obj.owner == request.user

View File

@ -0,0 +1,44 @@
# coding:utf-8
# @文件: serializers_app.py
# @创建者:州的先生
# #日期2020/5/11
# 博客地址zmister.com
from rest_framework.serializers import ModelSerializer
from app_doc.models import *
# 文集序列化器
class ProjectSerializer(ModelSerializer):
class Meta:
model = Project
fields = ('__all__')
# 文档序列化器
class DocSerializer(ModelSerializer):
class Meta:
model = Doc
fields = ('__all__')
# 文档模板序列化器
class DocTempSerializer(ModelSerializer):
class Meta:
model = DocTemp
fields = ('__all__')
# 图片序列化器
class ImageSerializer(ModelSerializer):
class Meta:
model = Image
fields = ('__all__')
# 图片分组序列化器
class ImageGroupSerializer(ModelSerializer):
class Meta:
model = ImageGroup
fields = ('__all__')
# 附件序列化器
class AttachmentSerializer(ModelSerializer):
class Meta:
model = Attachment
fields = ('__all__')

17
app_api/urls_app.py Normal file
View File

@ -0,0 +1,17 @@
# coding:utf-8
# @文件: urls_app.py
# @创建者:州的先生
# #日期2020/5/11
# 博客地址zmister.com
from django.urls import path,re_path
from app_api import views_app
urlpatterns = [
path('login/',views_app.LoginView.as_view()),# 登录
path('projects/',views_app.ProjectView.as_view()), # 文集
path('docs/',views_app.DocView.as_view()), # 文档
path('doctemps/',views_app.DocTempView.as_view()), # 文档模板
path('images/',views_app.ImageView.as_view()), # 图片
path('imggroups/',views_app.ImageGroupView.as_view()), # 图片分组
path('attachments/',views_app.AttachmentView.as_view()), # 附件
]

View File

@ -43,8 +43,6 @@ def manage_token(request):
)
return JsonResponse({'status':True,'data':token_str})
except:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("用户Token生成异常")
return JsonResponse({'status':False,'data':'生成出错,请重试!'})
@ -68,8 +66,6 @@ def get_projects(request):
except ObjectDoesNotExist:
return JsonResponse({'status':False,'data':'token无效'})
except:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("token获取文集异常")
return JsonResponse({'status':False,'data':'系统异常'})
@ -101,8 +97,6 @@ def create_doc(request):
except ObjectDoesNotExist:
return JsonResponse({'status': False, 'data': 'token无效'})
except:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("token创建文档异常")
return JsonResponse({'status':False,'data':'系统异常'})
@ -126,7 +120,5 @@ def upload_img(request):
except ObjectDoesNotExist:
return JsonResponse({'success': 0, 'data': 'token无效'})
except:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("token上传图片异常")
return JsonResponse({'success':0,'data':'上传出错'})

829
app_api/views_app.py Normal file
View File

@ -0,0 +1,829 @@
# coding:utf-8
# @文件: views_app.py
# @创建者:州的先生
# #日期2020/5/11
# 博客地址zmister.com
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q
from django.conf import settings
from rest_framework.views import APIView
from app_api.models import AppUserToken
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
from app_doc.models import *
from app_api.serializers_app import *
from app_api.auth_app import AppAuth,AppMustAuth
from app_doc.views import validateTitle
from app_doc.util_upload_img import img_upload,base_img_upload
from loguru import logger
import datetime
import os
'''
响应
code状态码
data数据
状态码
0成功
1资源未找到
2无权访问
3需要访问码
4系统异常
5参数不正确
6需要登录
'''
# 生成Token的函数
def get_token_code(username):
"""
根据用户名和时间戳来生成永不相同的token随机字符串
:param username: 字符串格式的用户名
:return: 字符串格式的Token
"""
import time
import hashlib
timestamp = str(time.time())
m = hashlib.md5(username.encode("utf-8"))
# md5 要传入字节类型的数据
m.update(timestamp.encode("utf-8"))
return m.hexdigest() # 将生成的随机字符串返回
# 登陆视图
class LoginView(APIView):
'''
登陆检测试图
1接收用户发过来的用户名和密码数据
2校验用户密码是否正确
- 成功就返回登陆成功,然后发Token
- 失败就返回错误提示
'''
def post(self,request):
res = {"code":0}
# 从post 里面取数据
# print(request.data)
username = request.data.get("username")
password = request.data.get("password")
# 查询用户是否存在、密码是否匹配
user_obj = authenticate(username=username, password=password)
if user_obj:
if user_obj.is_active:
# 生成Token
token = get_token_code(username)
# 保存或更新token
AppUserToken.objects.update_or_create(defaults={"token": token}, user=user_obj)
# 将token返回给用户
res["token"] = token
else:
res["error"] = '账号被禁用'
else:
# 登陆失败
res["code"] = 1
res["error"] = "用户名或密码错误"
return Response(res)
# 文集视图
class ProjectView(APIView):
authentication_classes = (AppAuth,)
# 获取文集
def get(self,request):
pro_id = request.query_params.get('id',None)
if pro_id:
resp = dict()
# 获取文集信息
project = Project.objects.get(id=int(pro_id))
# 获取文集的协作用户信息
# print(request.auth)
# print(request.user)
if request.auth: # 对登陆用户查询其协作文档信息
colla_user = ProjectCollaborator.objects.filter(project=project, user=request.user).count()
else:
colla_user = 0
# 获取文集前台下载权限
try:
allow_download = ProjectReport.objects.get(project=project)
except:
allow_download = False
# 私密文集并且访问者非创建者非协作者
if (project.role == 1) and (request.user != project.create_user) and (colla_user == 0):
# return Response({'code': 2, 'data': []})
resp['code'] = 2
# 指定用户可见文集
elif project.role == 2:
user_list = project.role_value
if request.auth: # 认证用户判断是否在许可用户列表中
if (request.user.username not in user_list) and \
(request.user != project.create_user) and \
(colla_user == 0): # 访问者不在指定用户之中
resp['code'] = 2
else: # 游客直接返回404
resp['code'] = 2
# 访问码可见
elif project.role == 3:
# 浏览用户不为创建者、协作者
if request.user != project.create_user and colla_user == 0:
viewcode = project.role_value
viewcode_name = 'viewcode-{}'.format(project.id)
r_viewcode = request.data.get(viewcode_name,0) # 获取访问码
if viewcode != r_viewcode: # 访问码不等于文集访问码,跳转到访问码认证界面
# return Response({'code': 3})
resp['code'] = 3
else:
serializer = ProjectSerializer(project)
resp = {'code': 0, 'data': serializer.data}
return Response(resp)
else:
kw = request.query_params.get('kw', '') # 搜索词
sort = request.query_params.get('sort', 0) # 排序,0表示按时间升序排序1表示按时间降序排序默认为0
role = request.query_params.get('role', -1) # 筛选文集权限,默认为显示所有可显示的文集
# 是否排序
if sort in ['', 0, '0']:
sort_str = ''
else:
sort_str = '-'
# 是否搜索
if kw == '':
is_kw = False
else:
is_kw = True
# 是否认证
if request.auth:
is_auth = True
else:
is_auth = False
# 是否筛选
if role in ['', -1, '-1']:
is_role = False
role_list = [0, 3]
else:
is_role = True
# 没有搜索 and 认证用户 and 没有筛选
if (is_kw is False) and (is_auth) and (is_role is False):
colla_list = [i.project.id for i in ProjectCollaborator.objects.filter(user=request.user)] # 用户的协作文集列表
project_list = Project.objects.filter(
Q(role__in=role_list) | \
Q(role=2, role_value__contains=str(request.user.username)) | \
Q(create_user=request.user) | \
Q(id__in=colla_list)
).order_by("{}create_time".format(sort_str))
# 没有搜索 and 认证用户 and 有筛选
elif (is_kw is False) and (is_auth) and (is_role):
if role in ['0', 0]:
project_list = Project.objects.filter(role=0).order_by("{}create_time".format(sort_str))
elif role in ['1', 1]:
project_list = Project.objects.filter(create_user=request.user, role=1).order_by(
"{}create_time".format(sort_str))
elif role in ['2', 2]:
project_list = Project.objects.filter(role=2, role_value__contains=str(request.user.username)).order_by(
"{}create_time".format(sort_str))
elif role in ['3', 3]:
project_list = Project.objects.filter(role=3).order_by("{}create_time".format(sort_str))
elif role in ['99', 99]:
colla_list = [i.project.id for i in ProjectCollaborator.objects.filter(user=request.user)] # 用户的协作文集列表
project_list = Project.objects.filter(id__in=colla_list).order_by("{}create_time".format(sort_str))
else:
return Response({'code':2,'data':[]})
# 没有搜索 and 游客 and 没有筛选
elif (is_kw is False) and (is_auth is False) and (is_role is False):
project_list = Project.objects.filter(role__in=[0, 3]).order_by("{}create_time".format(sort_str))
# 没有搜索 and 游客 and 有筛选
elif (is_kw is False) and (is_auth is False) and (is_role):
if role in ['0', 0]:
project_list = Project.objects.filter(role=0).order_by("{}create_time".format(sort_str))
elif role in ['3', 3]:
project_list = Project.objects.filter(role=3).order_by("{}create_time".format(sort_str))
else:
return Response({'code': 2, 'data': []})
# 有搜索 and 认证用户 and 没有筛选
elif (is_kw) and (is_auth) and (is_role is False):
colla_list = [i.project.id for i in ProjectCollaborator.objects.filter(user=request.user)] # 用户的协作文集
# 查询所有可显示的文集
project_list = Project.objects.filter(
Q(role__in=[0, 3]) | \
Q(role=2, role_value__contains=str(request.user.username)) | \
Q(create_user=request.user) | \
Q(id__in=colla_list),
Q(name__icontains=kw) | Q(intro__icontains=kw)
).order_by('{}create_time'.format(sort_str))
# 有搜索 and 认证用户 and 有筛选
elif (is_kw) and (is_auth) and (is_role):
if role in ['0', 0]:
project_list = Project.objects.filter(
Q(name__icontains=kw) | Q(intro__icontains=kw),
role=0
).order_by("{}create_time".format(sort_str))
elif role in ['1', 1]:
project_list = Project.objects.filter(
Q(name__icontains=kw) | Q(intro__icontains=kw),
create_user=request.user
).order_by("{}create_time".format(sort_str))
elif role in ['2', 2]:
project_list = Project.objects.filter(
Q(name__icontains=kw) | Q(intro__icontains=kw),
role=2,
role_value__contains=str(request.user.username)
).order_by("{}create_time".format(sort_str))
elif role in ['3', 3]:
project_list = Project.objects.filter(
Q(name__icontains=kw) | Q(intro__icontains=kw),
role=3
).order_by("{}create_time".format(sort_str))
elif role in ['99', 99]:
colla_list = [i.project.id for i in ProjectCollaborator.objects.filter(user=request.user)] # 用户的协作文集列表
project_list = Project.objects.filter(
Q(name__icontains=kw) | Q(intro__icontains=kw),
id__in=colla_list
).order_by("{}create_time".format(sort_str))
else:
return Response({'code':1,'data':[]})
# 有搜索 and 游客 and 没有筛选
elif (is_kw) and (is_auth is False) and (is_role is False):
project_list = Project.objects.filter(
Q(name__icontains=kw) | Q(intro__icontains=kw),
role__in=[0, 3]
).order_by("{}create_time".format(sort_str))
# 有搜索 and 游客 and 有筛选
elif (is_kw) and (is_auth is False) and (is_role):
if role in ['0', 0]:
project_list = Project.objects.filter(
Q(name__icontains=kw) | Q(intro__icontains=kw),
role=0
).order_by("{}create_time".format(sort_str))
elif role in ['3', 3]:
project_list = Project.objects.filter(
Q(name__icontains=kw) | Q(intro__icontains=kw),
role=3
).order_by("{}create_time".format(sort_str))
else:
return Response({'code':1,'data':[]})
page = PageNumberPagination() # 实例化一个分页器
page_projects = page.paginate_queryset(project_list,request,view=self) # 进行分页查询
serializer = ProjectSerializer(page_projects,many=True) # 对分页后的结果进行序列化处理
resp = {
'code':0,
'data':serializer.data,
'count':project_list.count()
}
return Response(resp)
# 新增文集
def post(self,request):
resp = dict()
if request.auth:
try:
name = request.data.get('pname', '')
name = validateTitle(name)
desc = request.data.get('desc', '')
role = request.data.get('role', 0)
role_list = ['0', '1', '2', '3', 0, 1, 2, 3]
if name != '':
project = Project.objects.create(
name=validateTitle(name),
intro=desc[:100],
create_user=request.user,
role=int(role) if role in role_list else 0
)
project.save()
resp = {'code':0,'data':{'id': project.id, 'name': project.name}}
return Response(resp)
else:
resp['code'] = 5
resp['data'] = '参数不正确'
return Response(resp)
except Exception as e:
logger.exception("创建文集出错")
resp['code'] = 4
resp['data'] = '系统异常请稍后再试'
return Response(resp)
else:
resp['code'] = 6
resp['data'] = '请登录后操作'
return Response(resp)
# 修改文集
def put(self,request):
resp = dict()
if request.auth:
try:
pro_id = request.query_params.get('id', None)
project = Project.objects.get(id=pro_id)
# 验证用户有权限修改文集
if (request.user == project.create_user) or request.user.is_superuser:
name = request.data.get('name', None)
content = request.data.get('desc', None)
role = request.data.get('role',None)
role_value = request.data.get('role_value',None)
project.name = validateTitle(name)
project.intro = content
project.role = role
project.role_value = role_value
project.save()
resp['code'] = 0
resp['data'] = 'ok'
# return Response(resp)
else:
resp['code'] = 2
resp['data'] = '非法请求'
# return Response(resp)
except ObjectDoesNotExist:
resp['code'] = 1
resp['data'] = '资源未找到'
# return Response(resp)
except Exception as e:
logger.exception("修改文集出错")
resp['code'] = 4
# return Response(resp)
else:
resp['code'] = 6
return Response(resp)
# 删除文集
def delete(self,request):
resp = dict()
if request.auth:
try:
pro_id = request.query_params.get('id', '')
if pro_id != '':
pro = Project.objects.get(id=pro_id)
if (request.user == pro.create_user) or request.user.is_superuser:
# 删除文集下的文档
pro_doc_list = Doc.objects.filter(top_doc=int(pro_id))
pro_doc_list.delete()
# 删除文集
pro.delete()
resp['code'] = 0
resp['data'] = 'ok'
# return Response(resp)
else:
resp['code'] = 2
# return Response(resp)
else:
resp['code'] = 5
resp['data'] = '参数错误'
# return Response(resp)
except ObjectDoesNotExist:
resp['code'] = 1
resp['data'] = '资源未找到'
# return Response(resp)
except Exception as e:
logger.exception("API文集删除异常")
resp['code'] = 4
# return Response(resp)
else:
resp['code'] = 6
return Response(resp)
# 文档视图
class DocView(APIView):
authentication_classes = (AppAuth,)
# 获取文档
def get(self,request):
pro_id = request.query_params.get('pid','')
doc_id = request.query_params.get('did','')
if pro_id != '' and doc_id != '':
# 获取文集信息
project = Project.objects.get(id=int(pro_id))
# 获取文集的协作用户信息
if request.auth:
colla_user = ProjectCollaborator.objects.filter(project=project, user=request.user)
if colla_user.exists():
colla_user_role = colla_user[0].role
colla_user = colla_user.count()
else:
colla_user = colla_user.count()
else:
colla_user = 0
# 私密文集且访问者非创建者、协作者 - 不能访问
if (project.role == 1) and (request.user != project.create_user) and (colla_user == 0):
return Response({'code':2})
# 指定用户可见文集
elif project.role == 2:
user_list = project.role_value
if request.user.is_authenticated: # 认证用户判断是否在许可用户列表中
if (request.user.username not in user_list) and \
(request.user != project.create_user) and \
(colla_user == 0): # 访问者不在指定用户之中,也不是协作者
return Response({'code': 2})
else: # 游客直接返回404
return Response({'code': 2})
# 访问码可见
elif project.role == 3:
# 浏览用户不为创建者和协作者 - 需要访问码
if (request.user != project.create_user) and (colla_user == 0):
viewcode = project.role_value
viewcode_name = 'viewcode-{}'.format(project.id)
r_viewcode = request.data.get(viewcode_name,0) # 获取访问码
if viewcode != r_viewcode: # cookie中的访问码不等于文集访问码跳转到访问码认证界面
return Response({'code':3})
# 获取文档内容
try:
doc = Doc.objects.get(id=int(doc_id), status=1)
serializer = DocSerializer(doc)
resp = {'code':0,'data':serializer.data}
return Response(resp)
except ObjectDoesNotExist:
return Response({'code':4})
else:
return Response({'code':4})
# 新建文档
def post(self, request):
try:
project = request.data.get('project','')
parent_doc = request.data.get('parent_doc','')
doc_name = request.data.get('doc_name','')
doc_content = request.data.get('content','')
pre_content = request.data.get('pre_content','')
sort = request.data.get('sort','')
status = request.data.get('status',1)
if project != '' and doc_name != '' and project != '-1':
# 验证请求者是否有文集的权限
check_project = Project.objects.filter(id=project,create_user=request.user)
colla_project = ProjectCollaborator.objects.filter(project=project,user=request.user)
if check_project.count() > 0 or colla_project.count() > 0:
# 创建文档
doc = Doc.objects.create(
name=doc_name,
content = doc_content,
pre_content= pre_content,
parent_doc= int(parent_doc) if parent_doc != '' else 0,
top_doc= int(project),
sort = sort if sort != '' else 99,
create_user=request.user,
status = status
)
return Response({'code':0,'data':{'pro':project,'doc':doc.id}})
else:
return Response({'code':2,'data':'无权操作此文集'})
else:
return Response({'code':5,'data':'请确认文档标题、文集正确'})
except Exception as e:
logger.exception("api新建文档异常")
return Response({'status':4,'data':'请求出错'})
# 修改文档
def put(self, request):
try:
doc_id = request.data.get('doc_id','') # 文档ID
project = request.data.get('project', '') # 文集ID
parent_doc = request.data.get('parent_doc', '') # 上级文档ID
doc_name = request.data.get('doc_name', '') # 文档名称
doc_content = request.data.get('content', '') # 文档内容
pre_content = request.data.get('pre_content', '') # 文档Markdown格式内容
sort = request.data.get('sort', '') # 文档排序
status = request.data.get('status',1) # 文档状态
if doc_id != '' and project != '' and doc_name != '' and project != '-1':
doc = Doc.objects.get(id=doc_id)
pro_colla = ProjectCollaborator.objects.filter(project=project, user=request.user)
# 验证用户有权限修改文档 - 文档的创建者或文集的高级协作者
if (request.user == doc.create_user) or (pro_colla[0].role == 1):
# 将现有文档内容写入到文档历史中
DocHistory.objects.create(
doc = doc,
pre_content = doc.pre_content,
create_user = request.user
)
# 更新文档内容
Doc.objects.filter(id=int(doc_id)).update(
name=doc_name,
content=doc_content,
pre_content=pre_content,
parent_doc=int(parent_doc) if parent_doc != '' else 0,
sort=sort if sort != '' else 99,
modify_time = datetime.datetime.now(),
status = status
)
return Response({'code': 0,'data':'修改成功'})
else:
return Response({'code':2,'data':'未授权请求'})
else:
return Response({'code': 5,'data':'参数错误'})
except Exception as e:
logger.exception("api修改文档出错")
return Response({'code':4,'data':'请求出错'})
# 删除文档
def delete(self, request):
try:
# 获取文档ID
doc_id = request.data.get('doc_id', None)
if doc_id:
# 查询文档
try:
doc = Doc.objects.get(id=doc_id)
except ObjectDoesNotExist:
return Response({'code': 1, 'data': '文档不存在'})
if request.user == doc.create_user:
# 删除
doc.delete()
# 修改其子文档为顶级文档
Doc.objects.filter(parent_doc=doc_id).update(parent_doc=0)
return Response({'code': 0, 'data': '删除完成'})
else:
return Response({'code': 2, 'data': '非法请求'})
else:
return Response({'code': 5, 'data': '参数错误'})
except Exception as e:
logger.exception("api删除文档出错")
return Response({'code': 4, 'data': '请求出错'})
# 文档模板视图
class DocTempView(APIView):
authentication_classes = (AppAuth,)
# 获取文档模板
def get(self, request):
if request.auth:
temp_id = request.query_params.get('id','')
if temp_id != '':
doctemp = DocTemp.objects.get(id=int(temp_id))
if request.user == doctemp.create_user:
serializer = DocTempSerializer(doctemp)
resp = {'code': 0, 'data': serializer.data}
else:
resp = {'code':2,'data':'无权操作'}
else:
doctemps = DocTemp.objects.filter(create_user=request.user)
page = PageNumberPagination()
page_doctemps = page.paginate_queryset(doctemps,request,view=self)
serializer = DocTempSerializer(page_doctemps,many=True)
resp = {'code':0,'data':serializer.data,'count':doctemps.count()}
return Response(resp)
else:
return Response({'code': 6, 'data': '请登录'})
def post(self, request):
try:
if request.auth:
name = request.data.get('name','')
content = request.data.get('content','')
if name != '':
doctemp = DocTemp.objects.create(
name = name,
content = content,
create_user=request.user
)
doctemp.save()
return Response({'code':0,'data':'创建成功'})
else:
return Response({'code':5,'data':'模板标题不能为空'})
else:
return Response({'code':6,'data':'请登录'})
except Exception as e:
logger.exception("api创建文档模板出错")
return Response({'code':4,'data':'请求出错'})
def put(self, request):
try:
doctemp_id = request.data.get('doctemp_id','')
name = request.data.get('name','')
content = request.data.get('content','')
if doctemp_id != '' and name !='':
doctemp = DocTemp.objects.get(id=doctemp_id)
# 验证请求用户为文档模板的创建者
if request.user == doctemp.create_user:
doctemp.name = name
doctemp.content = content
doctemp.save()
return Response({'code':0,'data':'修改成功'})
else:
return Response({'code':2,'data':'非法操作'})
else:
return Response({'code':5,'data':'参数错误'})
except Exception as e:
logger.exception("api修改文档模板出错")
return Response({'code':4,'data':'请求出错'})
def delete(self, request):
try:
doctemp_id = request.data.get('doctemp_id', '')
if doctemp_id != '':
doctemp = DocTemp.objects.get(id=doctemp_id)
if request.user == doctemp.create_user:
doctemp.delete()
return Response({'code': 0, 'data': '删除完成'})
else:
return Response({'code': 2, 'data': '非法请求'})
else:
return Response({'code': 5, 'data': '参数错误'})
except Exception as e:
logger.exception("api删除文档模板出错")
return Response({'code': 4, 'data': '请求出错'})
# 图片视图
class ImageView(APIView):
authentication_classes = (AppAuth,)
def get(self, request):
if request.auth:
g_id = int(request.query_params.get('group', 0)) # 图片分组id
if int(g_id) == 0:
image_list = Image.objects.filter(user=request.user) # 查询所有图片
elif int(g_id) == -1:
image_list = Image.objects.filter(user=request.user, group_id=None) # 查询指定分组的图片
else:
image_list = Image.objects.filter(user=request.user, group_id=g_id) # 查询指定分组的图片
page = PageNumberPagination()
page_images = page.paginate_queryset(image_list,request,view=self)
serializer = ImageSerializer(page_images,many=True)
resp = {'code':0,'data':serializer.data,'count':image_list.count()}
return Response(resp)
else:
return Response({'code': 6, 'data': '请登录'})
# 上传
def post(self, request):
img = request.data.get("api_img_upload", None) # 编辑器上传
# manage_upload = request.data.get('manage_upload', None) # 图片管理上传
dir_name = request.data.get('dirname', '')
base_img = request.data.get('base', None)
if img: # 上传普通图片文件
result = img_upload(img, dir_name, request.user)
resp = {'code':0,'data':result['url']}
# elif manage_upload:
# result = img_upload(manage_upload, dir_name, request.user)
# resp = {'code': 0, 'data': result['url']}
elif base_img: # 上传base64编码图片
result = base_img_upload(base_img, dir_name, request.user)
resp = {'code': 0, 'data': result['url']}
else:
resp = {"code": 5, "message": "出错信息"}
return Response(resp)
# 删除
def delete(self, request):
img_id = request.data.get('id', '')
img = Image.objects.get(id=img_id)
if img.user != request.user:
return Response({'code': 2, 'data': '未授权请求'})
file_path = settings.BASE_DIR + img.file_path
is_exist = os.path.exists(file_path)
if is_exist:
os.remove(file_path) # 删除本地文件
img.delete() # 删除记录
return Response({'code': 0, 'data': 'ok'})
# 图片分组视图
class ImageGroupView(APIView):
authentication_classes = (AppMustAuth,)
def get(self, request):
try:
group_list = []
all_cnt = Image.objects.filter(user=request.user).count()
non_group_cnt = Image.objects.filter(group_id=None,user=request.user).count()
group_list.append({'group_name': '全部图片', 'group_cnt': all_cnt, 'group_id': 0})
group_list.append({'group_name': '未分组', 'group_cnt': non_group_cnt, 'group_id': -1})
groups = ImageGroup.objects.filter(user=request.user) # 查询所有分组
for group in groups:
group_cnt = Image.objects.filter(group_id=group).count()
item = {
'group_id': group.id,
'group_name': group.group_name,
'group_cnt': group_cnt
}
group_list.append(item)
return Response({'code': 0, 'data': group_list})
except:
return Response({'code': 4, 'data': '出现错误'})
def post(self, request):
group_name = request.data.get('group_name', '')
if group_name not in ['', '默认分组', '未分组']:
ImageGroup.objects.create(
user=request.user,
group_name=group_name
)
return Response({'code': 0, 'data': 'ok'})
else:
return Response({'code': 5, 'data': '名称无效'})
def put(self, request):
group_name = request.data.get("group_name", '')
if group_name not in ['', '默认分组', '未分组']:
group_id = request.POST.get('group_id', '')
ImageGroup.objects.filter(id=group_id,user=request.user).update(group_name=group_name)
return Response({'code': 0, 'data': 'ok'})
else:
return Response({'code': 5, 'data': '名称无效'})
def delete(self, request):
try:
group_id = request.data.get('group_id', '')
group = ImageGroup.objects.get(id=group_id, user=request.user) # 查询分组
images = Image.objects.filter(group_id=group_id).update(group_id=None) # 移动图片到未分组
group.delete() # 删除分组
return Response({'code': 0, 'data': 'ok'})
except:
return Response({'code': 4, 'data': '删除错误'})
# 附件视图
class AttachmentView(APIView):
authentication_classes = (AppAuth,)
# 文件大小 字节转换
def sizeFormat(size, is_disk=False, precision=2):
'''
size format for human.
byte ---- (B)
kilobyte ---- (KB)
megabyte ---- (MB)
gigabyte ---- (GB)
terabyte ---- (TB)
petabyte ---- (PB)
exabyte ---- (EB)
zettabyte ---- (ZB)
yottabyte ---- (YB)
'''
formats = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
unit = 1000.0 if is_disk else 1024.0
if not (isinstance(size, float) or isinstance(size, int)):
raise TypeError('a float number or an integer number is required!')
if size < 0:
raise ValueError('number must be non-negative')
for i in formats:
size /= unit
if size < unit:
r = '{}{}'.format(round(size, precision), i)
return r
def get(self, request):
attachment_list = []
attachments = Attachment.objects.filter(user=request.user)
for a in attachments:
item = {
'filename': a.file_name,
'filesize': a.file_size,
'filepath': a.file_path.name,
'filetime': a.create_time
}
attachment_list.append(item)
return Response({'code': 0, 'data': attachment_list})
def post(self, request):
attachment = request.data.get('attachment_upload', None)
if attachment:
attachment_name = attachment.name
attachment_size = self.sizeFormat(attachment.size)
# 限制附件大小在50mb以内
if attachment.size > 52428800:
return Response({'code': False, 'data': '文件大小超出限制'})
# 限制附件为ZIP格式文件
if attachment_name.endswith('.zip'):
a = Attachment.objects.create(
file_name=attachment_name,
file_size=attachment_size,
file_path=attachment,
user=request.user
)
return Response({'code': 0, 'data': {'name': attachment_name, 'url': a.file_path.name}})
else:
return Response({'code': 5, 'data': '不支持的格式'})
else:
return Response({'code': 5, 'data': '无效文件'})
def delete(self, request):
attach_id = request.data.get('attach_id', '')
attachment = Attachment.objects.filter(id=attach_id, user=request.user) # 查询附件
for a in attachment: # 遍历附件
a.file_path.delete() # 删除文件
attachment.delete() # 删除数据库记录
return Response({'code': 0, 'data': 'ok'})

View File

@ -43,7 +43,21 @@ def geneta_js_img(html_path,img_path,types):
'seque':'.sequence-diagram' # 序列图
}
async def main():
browser = await launch(headless=True,handleSIGINT=False,handleSIGTERM=False,handleSIGHUP=False)
if settings.CHROMIUM_PATH:
browser = await launch(
executablePath=r'{}'.format(settings.CHROMIUM_PATH),
headless=True,
handleSIGINT=False,
handleSIGTERM=False,
handleSIGHUP=False
)
else:
browser = await launch(
headless=True,
handleSIGINT=False,
handleSIGTERM=False,
handleSIGHUP=False
)
page = await browser.newPage()
await page.goto('file://' + html_path, {'waitUntil': 'networkidle0'})
element = await page.querySelector(type_map[types])
@ -66,13 +80,21 @@ def geneta_js_img(html_path,img_path,types):
@logger.catch()
def html_to_pdf(html_path,pdf_path):
async def main():
browser = await launch(
headless=True,
handleSIGINT=False,
handleSIGTERM=False,
handleSIGHUP=False,
ignoreHTTPSErrors = True,
)
if settings.CHROMIUM_PATH:
browser = await launch(
executablePath=r'{}'.format(settings.CHROMIUM_PATH),
headless=True,
handleSIGINT=False,
handleSIGTERM=False,
handleSIGHUP=False
)
else:
browser = await launch(
headless=True,
handleSIGINT=False,
handleSIGTERM=False,
handleSIGHUP=False
)
page = await browser.newPage()
await page.goto('file://' + html_path, {'waitUntil': 'networkidle0'})
await page.pdf({

View File

@ -194,8 +194,7 @@ def create_project(request):
else:
return JsonResponse({'status':False,'data':'文集名称不能为空!'})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("创建文集出错")
return JsonResponse({'status':False,'data':'出现异常,请检查输入值!'})
@ -252,8 +251,6 @@ def project_index(request,pro_id):
return render(request,'app_doc/project_doc_search.html',locals())
return render(request, 'app_doc/project.html', locals())
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("文集页访问异常")
return render(request,'404.html')
@ -276,8 +273,6 @@ def modify_project(request):
else:
return JsonResponse({'status':False,'data':'非法请求'})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("修改文集出错")
return JsonResponse({'status':False,'data':'请求出错'})
@ -344,8 +339,6 @@ def check_viewcode(request):
errormsg = "访问码错误"
return render(request, 'app_doc/check_viewcode.html', locals())
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("验证文集访问码出错")
return render(request,'404.html')
@ -370,8 +363,6 @@ def del_project(request):
else:
return JsonResponse({'status':False,'data':'参数错误'})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("删除文集出错")
return JsonResponse({'status':False,'data':'请求出错'})
@ -405,8 +396,6 @@ def manage_project(request):
pros = paginator.page(paginator.num_pages)
return render(request,'app_doc/manage_project.html',locals())
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("管理文集出错")
return render(request,'404.html')
@ -499,8 +488,7 @@ def manage_project_collaborator(request,pro_id):
pro_colla.delete()
return JsonResponse({'status':True,'data':'删除成功'})
except:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("删除协作者出错")
return JsonResponse({'status':False,'data':'删除出错'})
# 修改协作权限
elif int(types) == 2:
@ -512,8 +500,7 @@ def manage_project_collaborator(request,pro_id):
pro_colla.update(role=role)
return JsonResponse({'status':True,'data':'修改成功'})
except:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("修改协作权限出错")
return JsonResponse({'status':False,'data':'修改失败'})
else:
@ -574,8 +561,6 @@ def doc(request,pro_id,doc_id):
try:
doc = Doc.objects.get(id=int(doc_id),status=1)
except ObjectDoesNotExist:
if settings.DEBUG:
print(traceback.print_exc())
return render(request, '404.html')
# 获取文集下一级文档
project_docs = Doc.objects.filter(top_doc=doc.top_doc, parent_doc=0, status=1).order_by('sort')
@ -583,8 +568,6 @@ def doc(request,pro_id,doc_id):
else:
return HttpResponse('参数错误')
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("文集浏览出错")
return render(request,'404.html')
@ -602,8 +585,7 @@ def create_doc(request):
doctemp_list = DocTemp.objects.filter(create_user=request.user).values('id','name','create_time')
return render(request,'app_doc/create_doc.html',locals())
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("访问创建文档页面出错")
return render(request,'404.html')
elif request.method == 'POST':
try:
@ -636,8 +618,7 @@ def create_doc(request):
else:
return JsonResponse({'status':False,'data':'请确认文档标题、文集正确'})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("创建文档出错")
return JsonResponse({'status':False,'data':'请求出错'})
else:
return JsonResponse({'status':False,'data':'方法不允许'})
@ -660,8 +641,6 @@ def modify_doc(request,doc_id):
else:
return render(request,'403.html')
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("修改文档页面访问出错")
return render(request,'404.html')
elif request.method == 'POST':
@ -702,8 +681,6 @@ def modify_doc(request,doc_id):
else:
return JsonResponse({'status': False,'data':'参数错误'})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("修改文档出错")
return JsonResponse({'status':False,'data':'请求出错'})
@ -732,8 +709,6 @@ def del_doc(request):
else:
return JsonResponse({'status':False,'data':'参数错误'})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("删除文档出错")
return JsonResponse({'status':False,'data':'请求出错'})
@ -851,8 +826,6 @@ def diff_doc(request,doc_id,his_id):
else:
return render(request, '403.html')
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("文档历史版本页面访问出错")
return render(request, '404.html')
@ -870,8 +843,6 @@ def diff_doc(request,doc_id,his_id):
else:
return JsonResponse({'status':False,'data':'非法请求'})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("文档历史版本获取出错")
return JsonResponse({'status':False,'data':'获取异常'})
@ -894,8 +865,6 @@ def manage_doc_history(request,doc_id):
historys = paginator.page(paginator.num_pages)
return render(request, 'app_doc/manage_doc_history.html', locals())
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("管理文档历史版本页面访问出错")
return render(request, '404.html')
elif request.method == 'POST':
@ -904,8 +873,6 @@ def manage_doc_history(request,doc_id):
DocHistory.objects.filter(id=history_id,doc=doc_id,create_user=request.user).delete()
return JsonResponse({'status':True,'data':'删除成功'})
except:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("操作文档历史版本出错")
return JsonResponse({'status':False,'data':'出现异常'})
@ -932,8 +899,6 @@ def create_doctemp(request):
else:
return JsonResponse({'status':False,'data':'模板标题不能为空'})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("创建文档模板出错")
return JsonResponse({'status':False,'data':'请求出错'})
@ -951,8 +916,6 @@ def modify_doctemp(request,doctemp_id):
else:
return HttpResponse('非法请求')
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("访问文档模板修改页面出错")
return render(request, '404.html')
elif request.method == 'POST':
@ -972,8 +935,6 @@ def modify_doctemp(request,doctemp_id):
else:
return JsonResponse({'status':False,'data':'参数错误'})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("修改文档模板出错")
return JsonResponse({'status':False,'data':'请求出错'})
@ -993,8 +954,6 @@ def del_doctemp(request):
else:
return JsonResponse({'status': False, 'data': '参数错误'})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("删除文档模板出错")
return JsonResponse({'status':False,'data':'请求出错'})
@ -1006,7 +965,10 @@ def manage_doctemp(request):
try:
search_kw = request.GET.get('kw', None)
if search_kw:
doctemp_list = DocTemp.objects.filter(create_user=request.user,content__icontains=search_kw)
doctemp_list = DocTemp.objects.filter(
create_user=request.user,
content__icontains=search_kw
).order_by('-modify_time')
paginator = Paginator(doctemp_list, 10)
page = request.GET.get('page', 1)
try:
@ -1017,7 +979,7 @@ def manage_doctemp(request):
doctemps = paginator.page(paginator.num_pages)
doctemps.kw = search_kw
else:
doctemp_list = DocTemp.objects.filter(create_user=request.user)
doctemp_list = DocTemp.objects.filter(create_user=request.user).order_by('-modify_time')
paginator = Paginator(doctemp_list, 10)
page = request.GET.get('page', 1)
try:
@ -1028,8 +990,6 @@ def manage_doctemp(request):
doctemps = paginator.page(paginator.num_pages)
return render(request, 'app_doc/manage_doctemp.html', locals())
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("管理文档模板页面访问出错")
return render(request, '404.html')
@ -1046,8 +1006,6 @@ def get_doctemp(request):
else:
return JsonResponse({'status':False,'data':'参数错误'})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("获取指定文档模板出错")
return JsonResponse({'status':False,'data':'请求出错'})
@ -1163,8 +1121,6 @@ def report_md(request):
else:
return JsonResponse({'status':False,'data':'无权限'})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("导出文集MD文件出错")
return JsonResponse({'status':False,'data':'文集不存在'})
@ -1262,8 +1218,6 @@ def genera_project_file(request):
return JsonResponse({'status': True, 'data': epub_file})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
return JsonResponse({'status': False, 'data': '生成出错'})
# 导出PDF
elif report_type in ['pdf']:
@ -1296,8 +1250,6 @@ def genera_project_file(request):
return JsonResponse({'status': True, 'data': pdf_file})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
return JsonResponse({'status': False, 'data': '生成出错'})
else:
return JsonResponse({'status': False, 'data': '不支持的类型'})
@ -1309,8 +1261,6 @@ def genera_project_file(request):
return JsonResponse({'status':False,'data':'文集不存在'})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("生成文集文件出错")
return JsonResponse({'status':False,'data':'系统异常'})
@ -1387,8 +1337,6 @@ def report_file(request):
# print(report_project)
return JsonResponse({'status': True, 'data': report_project.file_path})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
return JsonResponse({'status': False, 'data': '导出出错'})
# 导出PDF
elif report_type in ['pdf']:
@ -1400,8 +1348,6 @@ def report_file(request):
# print(report_project)
return JsonResponse({'status': True, 'data': report_project.file_path})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
return JsonResponse({'status': False, 'data': '导出出错'})
else:
return JsonResponse({'status': False, 'data': '不支持的类型'})
@ -1410,8 +1356,6 @@ def report_file(request):
except ObjectDoesNotExist:
return JsonResponse({'status':False,'data':'文集不存在'})
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("获取文集前台导出文件出错")
return JsonResponse({'status':False,'data':'系统异常'})
@ -1428,11 +1372,11 @@ def manage_image(request):
no_group_cnt = Image.objects.filter(user=request.user,group_id=None).count() # 获取所有未分组的图片数量
g_id = int(request.GET.get('group', 0)) # 图片分组id
if int(g_id) == 0:
image_list = Image.objects.filter(user=request.user) # 查询所有图片
image_list = Image.objects.filter(user=request.user).order_by('-create_time') # 查询所有图片
elif int(g_id) == -1:
image_list = Image.objects.filter(user=request.user,group_id=None) # 查询指定分组的图片
image_list = Image.objects.filter(user=request.user,group_id=None).order_by('-create_time') # 查询指定分组的图片
else:
image_list = Image.objects.filter(user=request.user,group_id=g_id) # 查询指定分组的图片
image_list = Image.objects.filter(user=request.user,group_id=g_id).order_by('-create_time') # 查询指定分组的图片
paginator = Paginator(image_list, 18)
page = request.GET.get('page', 1)
try:
@ -1444,8 +1388,6 @@ def manage_image(request):
images.group = g_id
return render(request,'app_doc/manage_image.html',locals())
except:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("图片素材管理出错")
return render(request,'404.html')
elif request.method == 'POST':
@ -1478,11 +1420,11 @@ def manage_image(request):
if group_id is None: #
return JsonResponse({'status':False,'data':'参数错误'})
elif int(group_id) == 0:
imgs = Image.objects.filter(user=request.user)
imgs = Image.objects.filter(user=request.user).order_by('-create_time')
elif int(group_id) == -1:
imgs = Image.objects.filter(user=request.user,group_id=None)
imgs = Image.objects.filter(user=request.user,group_id=None).order_by('-create_time')
else:
imgs = Image.objects.filter(user=request.user,group_id=group_id)
imgs = Image.objects.filter(user=request.user,group_id=group_id).order_by('-create_time')
img_list = []
for img in imgs:
item = {
@ -1496,8 +1438,6 @@ def manage_image(request):
except ObjectDoesNotExist:
return JsonResponse({'status':False,'data':'图片不存在'})
except:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("操作图片素材出错")
return JsonResponse({'status':False,'data':'程序异常'})
@ -1542,8 +1482,7 @@ def manage_img_group(request):
group.delete() # 删除分组
return JsonResponse({'status':True,'data':'删除完成'})
except:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("删除图片分组出错")
return JsonResponse({'status':False,'data':'删除错误'})
# 获取分组
elif int(types) == 3:
@ -1564,8 +1503,7 @@ def manage_img_group(request):
group_list.append(item)
return JsonResponse({'status':True,'data':group_list})
except:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("获取图片分组出错")
return JsonResponse({'status':False,'data':'出现错误'})
@ -1603,7 +1541,10 @@ def manage_attachment(request):
try:
search_kw = request.GET.get('kw', None)
if search_kw:
attachment_list = Attachment.objects.filter(user=request.user,file_name__icontains=search_kw)
attachment_list = Attachment.objects.filter(
user=request.user,
file_name__icontains=search_kw
).order_by('-create_time')
paginator = Paginator(attachment_list, 15)
page = request.GET.get('page', 1)
try:
@ -1614,7 +1555,7 @@ def manage_attachment(request):
attachments = paginator.page(paginator.num_pages)
attachments.kw = search_kw
else:
attachment_list = Attachment.objects.filter(user=request.user)
attachment_list = Attachment.objects.filter(user=request.user).order_by('-create_time')
paginator = Paginator(attachment_list, 15)
page = request.GET.get('page', 1)
try:
@ -1625,8 +1566,6 @@ def manage_attachment(request):
attachments = paginator.page(paginator.num_pages)
return render(request, 'app_doc/manage_attachment.html', locals())
except Exception as e:
if settings.DEBUG:
print(traceback.print_exc())
logger.exception("附件管理访问出错")
return render(request,'404.html')
elif request.method == 'POST':

View File

@ -14,4 +14,7 @@ engine = sqlite
# host表示数据库主机地址
# host = db_host
# port表示数据库端口
# port = db_port
# port = db_port
[chromium]
# path用于指定Chromium的路径不指定则使用默认的
# path = chromium_path

View File

@ -3,4 +3,5 @@ beautifulsoup4==4.8.2
lxml
pillow==6.2.2
pyppeteer==0.0.25
loguru==0.4.1
loguru==0.4.1
djangorestframework==3.8.2