Skip to content

Commit

Permalink
添加api应用、优化代码
Browse files Browse the repository at this point in the history
  • Loading branch information
yangjian committed May 16, 2020
1 parent 91e0615 commit a884179
Show file tree
Hide file tree
Showing 18 changed files with 1,119 additions and 125 deletions.
8 changes: 8 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
## 版本更新记录

### v0.5.2

- 添加Chrome内核浏览器扩展
- 添加API访问接口;
- 优化配置路径;
- 增强代码安全性;
- 优化个人中心图片、文档模板的默认排序;

### v0.5.1 2020-05-08

- 优化个人中心交互体验;
Expand Down
10 changes: 0 additions & 10 deletions MrDoc/__init__.py
Original file line number Diff line number Diff line change
@@ -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')
28 changes: 26 additions & 2 deletions MrDoc/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

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__)))
Expand All @@ -22,6 +23,13 @@
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/
Expand All @@ -32,11 +40,10 @@
# 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 = [
Expand All @@ -50,6 +57,7 @@
'app_doc',
'app_api',
'django.contrib.sitemaps',
'rest_framework',
]

MIDDLEWARE = [
Expand Down Expand Up @@ -80,6 +88,10 @@
'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',
},
},
},
]
Expand Down Expand Up @@ -168,3 +180,15 @@
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
1 change: 1 addition & 0 deletions MrDoc/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
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',), # 站点地图索引
Expand Down
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@

### 介绍

`MrDoc`是基于`Python`开发的在线文档系统,适合作为个人和小型团队的文档、知识和笔记管理工具。
`MrDoc`是基于`Python`开发的在线文档系统,适合作为个人和小型团队的文档、知识和笔记管理工具。致力于成为全平台(Web端、桌面端、移动端)的私有化在线文档部署方案。

目前涵盖:

- Web端,;
- Chrome扩展;
- App端(开发中)
- Windows、Mac、Linux桌面端(开发中)

### 开源地址

Expand Down Expand Up @@ -140,6 +147,8 @@ python manage.py runserver

## 赞赏项目

如果MrDoc对你有所帮助,欢迎给予开发者赞赏,助力项目更好发展。
开源不易,需要鼓励,如果MrDoc觅道文档对你有所帮助,请给予一个`Star`

欢迎给予开发者赞赏,助力项目更好发展。

![](./captrue/mrdoc-zan.png)
8 changes: 0 additions & 8 deletions app_admin/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)))

Expand Down Expand Up @@ -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('请求出错')

Expand Down Expand Up @@ -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'])

Expand Down Expand Up @@ -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())
Expand Down
52 changes: 52 additions & 0 deletions app_api/auth_app.py
Original file line number Diff line number Diff line change
@@ -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
28 changes: 28 additions & 0 deletions app_api/migrations/0003_appusertoken.py
Original file line number Diff line number Diff line change
@@ -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',
},
),
]
14 changes: 13 additions & 1 deletion app_api/models.py
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -12,3 +12,15 @@ def __str__(self):
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
31 changes: 31 additions & 0 deletions app_api/permissions_app.py
Original file line number Diff line number Diff line change
@@ -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
44 changes: 44 additions & 0 deletions app_api/serializers_app.py
Original file line number Diff line number Diff line change
@@ -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 changes: 17 additions & 0 deletions app_api/urls_app.py
Original file line number Diff line number Diff line change
@@ -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()), # 附件
]
Loading

0 comments on commit a884179

Please sign in to comment.