diff --git a/account/decorators.py b/account/decorators.py index d2ed1acd..2efdb99e 100644 --- a/account/decorators.py +++ b/account/decorators.py @@ -6,7 +6,7 @@ import functools from django.http import HttpResponseRedirect from django.utils.translation import ugettext as _ -from utils.shortcuts import error_response, error_page +from utils.shortcuts import error_response, error_page, redirect_to_login from .models import AdminType @@ -34,7 +34,7 @@ class BasePermissionDecorator(object): if self.request.is_ajax(): return error_response(_("Please login in first")) else: - return HttpResponseRedirect("/login/?__from=" + urllib.quote(self.request.path)) + return redirect_to_login(self.request) def check_permission(self): raise NotImplementedError() @@ -47,9 +47,11 @@ class login_required(BasePermissionDecorator): class super_admin_required(BasePermissionDecorator): def check_permission(self): - return self.request.user.is_authenticated() and self.request.user.admin_type == AdminType.SUPER_ADMIN + return self.request.user.is_authenticated() and \ + self.request.user.admin_type == AdminType.SUPER_ADMIN class admin_required(BasePermissionDecorator): def check_permission(self): - return self.request.user.is_authenticated() and self.request.user.admin_type in [AdminType.SUPER_ADMIN, AdminType.ADMIN] + return self.request.user.is_authenticated() and \ + self.request.user.admin_type in [AdminType.SUPER_ADMIN, AdminType.ADMIN] diff --git a/account/middleware.py b/account/middleware.py index 91081e9a..8d024c49 100644 --- a/account/middleware.py +++ b/account/middleware.py @@ -3,27 +3,24 @@ import time import json import urllib -from django.http import HttpResponseRedirect, HttpResponse +from django.http import HttpResponse from django.utils.translation import ugettext as _ -from django.contrib import auth -from .models import AdminType, User +from utils.shortcuts import redirect_to_login +from .models import AdminType -# todo remove this -from django.contrib import auth - class SessionSecurityMiddleware(object): def process_request(self, request): if request.user.is_authenticated() and request.user.admin_type in [AdminType.ADMIN, AdminType.SUPER_ADMIN]: if "last_activity" in request.session: - # 24 hours passwd since last visit + # 24 hours passed since last visit if time.time() - request.session["last_activity"] >= 24 * 60 * 60: auth.logout(request) if request.is_ajax(): return HttpResponse(json.dumps({"code": 1, "data": _("Please login in first")}), content_type="application/json") else: - return HttpResponseRedirect("/login/?__from=" + urllib.quote(request.path)) + return redirect_to_login(request) # 更新最后活动日期 request.session["last_activity"] = time.time() diff --git a/account/views.py b/account/views.py index b979aba4..4e997be8 100644 --- a/account/views.py +++ b/account/views.py @@ -1,38 +1,35 @@ # coding=utf-8 -import os -import codecs -import qrcode import StringIO +import codecs +import os -from django import http +import qrcode +from django.conf import settings from django.contrib import auth -from django.shortcuts import render +from django.core.exceptions import MultipleObjectsReturned from django.core.paginator import Paginator from django.db.models import Q -from django.conf import settings -from django.http import HttpResponse -from django.core.exceptions import MultipleObjectsReturned +from django.http import HttpResponse, HttpResponseRedirect +from django.shortcuts import render from django.utils.timezone import now from django.utils.translation import ugettext as _ - -from rest_framework.views import APIView from rest_framework.response import Response +from rest_framework.views import APIView -from utils.shortcuts import (serializer_invalid_response, error_response, - success_response, error_page, paginate, rand_str) from utils.captcha import Captcha from utils.otp_auth import OtpAuth - -from .tasks import _send_email +from utils.shortcuts import (serializer_invalid_response, error_response, + success_response, error_page, paginate, rand_str) from .decorators import login_required -from .models import User, UserProfile, AdminExtraPermission, AdminType +from .decorators import super_admin_required +from .models import User, UserProfile, AdminType from .serializers import (UserLoginSerializer, UserRegisterSerializer, UserChangePasswordSerializer, UserSerializer, EditUserSerializer, ApplyResetPasswordSerializer, ResetPasswordSerializer, SSOSerializer, EditUserProfileSerializer, TwoFactorAuthCodeSerializer) -from .decorators import super_admin_required +from .tasks import _send_email class UserLoginAPIView(APIView): @@ -223,7 +220,7 @@ class UserAdminAPIView(APIView): def logout(request): auth.logout(request) - return http.HttpResponseRedirect("/") + return HttpResponseRedirect("/") def index_page(request): @@ -233,7 +230,7 @@ def index_page(request): if request.META.get('HTTP_REFERER') or request.GET.get("index"): return render(request, "oj/index.html") else: - return http.HttpResponseRedirect('/problems/') + return HttpResponseRedirect('/problems/') class UsernameCheckAPIView(APIView): diff --git a/frontend/admin/index.html b/frontend/admin/index.html index d2ab8fba..2a4e8bc6 100644 --- a/frontend/admin/index.html +++ b/frontend/admin/index.html @@ -6,7 +6,6 @@
-
diff --git a/frontend/admin/package.json b/frontend/admin/package.json index f8f57e01..0270e4ed 100644 --- a/frontend/admin/package.json +++ b/frontend/admin/package.json @@ -33,6 +33,7 @@ "json-loader": "^0.5.4", "ora": "^0.2.0", "shelljs": "^0.6.0", + "simditor-markdown": "^1.1.2", "url-loader": "^0.5.7", "vue-hot-reload-api": "^1.2.0", "vue-html-loader": "^1.0.0", @@ -44,6 +45,7 @@ "webpack": "^1.12.2", "webpack-dev-middleware": "^1.4.0", "webpack-hot-middleware": "^2.6.0", - "webpack-merge": "^0.8.3" + "webpack-merge": "^0.8.3", + "webuploader": "^0.1.8" } } diff --git a/frontend/admin/src/App.vue b/frontend/admin/src/App.vue index d9f3fae3..6b5b5184 100644 --- a/frontend/admin/src/App.vue +++ b/frontend/admin/src/App.vue @@ -22,8 +22,8 @@ \ No newline at end of file diff --git a/frontend/admin/src/components/utils/alert.vue b/frontend/admin/src/components/utils/alert.vue index b41c2688..2ad7fd1a 100644 --- a/frontend/admin/src/components/utils/alert.vue +++ b/frontend/admin/src/components/utils/alert.vue @@ -39,10 +39,10 @@ } }, events: { - "showModal":(content) => { + "showModal": (content) => { this.showModal = true; this.content = true; - setTimeout(()=>{ + setTimeout(()=> { this.showModal = false; }, 2000); } diff --git a/frontend/admin/src/components/utils/leftNav.vue b/frontend/admin/src/components/utils/leftNav.vue index f2788795..7bf5f113 100644 --- a/frontend/admin/src/components/utils/leftNav.vue +++ b/frontend/admin/src/components/utils/leftNav.vue @@ -9,11 +9,11 @@ \ No newline at end of file diff --git a/frontend/admin/src/components/utils/simditor.vue b/frontend/admin/src/components/utils/simditor.vue new file mode 100644 index 00000000..cf9f1924 --- /dev/null +++ b/frontend/admin/src/components/utils/simditor.vue @@ -0,0 +1,25 @@ + + + + \ No newline at end of file diff --git a/frontend/admin/src/components/utils/uploader.vue b/frontend/admin/src/components/utils/uploader.vue new file mode 100644 index 00000000..f0ee62e4 --- /dev/null +++ b/frontend/admin/src/components/utils/uploader.vue @@ -0,0 +1,52 @@ + + + + + + \ No newline at end of file diff --git a/frontend/admin/src/locales.js b/frontend/admin/src/locales.js index a7f70a0a..f642cf5e 100644 --- a/frontend/admin/src/locales.js +++ b/frontend/admin/src/locales.js @@ -1,51 +1,51 @@ export default { - "zh-cn": { - nav: { - UserManagement: "用户管理" - }, - pagination: { - first: "首页", - last: "末页" - }, - modalAlert: { - alert: "提示", - close: "关闭" - }, - request: { - error: "请求失败", - succeeded: "操作成功" - }, - user: { - username: "用户名", - email: "邮箱", - realName: "真实姓名", - adminType: "用户类型", - createTime: "注册时间", - management: "管理", - edit: "编辑", - submission: "提交", - newPassword: "新密码", - leaveBlankIfDoNotChangePassword: "不需要修改密码请留空", - openAPIFunction: "OpenAPI 功能", - tfaAuth: "两步验证", - isDisabled: "禁用用户", - adminExtraPermission: "普通管理员额外权限", - showAdminOnly: "只显示管理员" - }, - adminUtils: { - search: "搜索", - inputKeyword: "输入关键词", - regularUser: "普通用户", - admin: "普通管理员", - superAdmin: "超级管理员", - UserDoesNotExist: "用户不存在", - back: "返回", - saveChanges: "保存修改", - createPublicContest: "创建公开比赛", - manageAllContest: "管理所有比赛", - manageAllProblem: "管理所有题目", - manageOwnProblem: "管理自己创建的题目", - unsupportedBrowserWarningMsg: "当前网页 不支持 你正在使用的浏览器, 为了正常的访问,请到 升级你的浏览器" - } - } + "zh-cn": { + nav: { + UserManagement: "用户管理" + }, + pagination: { + first: "首页", + last: "末页" + }, + modalAlert: { + alert: "提示", + close: "关闭" + }, + request: { + error: "请求失败", + succeeded: "操作成功" + }, + user: { + username: "用户名", + email: "邮箱", + realName: "真实姓名", + adminType: "用户类型", + createTime: "注册时间", + management: "管理", + edit: "编辑", + submission: "提交", + newPassword: "新密码", + leaveBlankIfDoNotChangePassword: "不需要修改密码请留空", + openAPIFunction: "OpenAPI 功能", + tfaAuth: "两步验证", + isDisabled: "禁用用户", + adminExtraPermission: "普通管理员额外权限", + showAdminOnly: "只显示管理员" + }, + adminUtils: { + search: "搜索", + inputKeyword: "输入关键词", + regularUser: "普通用户", + admin: "普通管理员", + superAdmin: "超级管理员", + UserDoesNotExist: "用户不存在", + back: "返回", + saveChanges: "保存修改", + createPublicContest: "创建公开比赛", + manageAllContest: "管理所有比赛", + manageAllProblem: "管理所有题目", + manageOwnProblem: "管理自己创建的题目", + unsupportedBrowserWarningMsg: "当前网页 不支持 你正在使用的浏览器, 为了正常的访问,请到 升级你的浏览器" + } + } }; \ No newline at end of file diff --git a/frontend/admin/src/main.js b/frontend/admin/src/main.js index 01c5246f..b1556a4c 100644 --- a/frontend/admin/src/main.js +++ b/frontend/admin/src/main.js @@ -7,6 +7,8 @@ import locale from "./locales" import userList from "./components/account/userList.vue" import editUser from "./components/account/editUser.vue" +import problem from "./components/problem/problem.vue" +import uploader from "./components/utils/uploader.vue" var request = { @@ -83,6 +85,10 @@ router.map({ "/user/edit/:userId": { name: "editUser", component: editUser + }, + "/problem/create": { + name: "createProblem", + component: problem } }); diff --git a/frontend/static/css/simditor-markdown.css b/frontend/static/css/simditor-markdown.css new file mode 100644 index 00000000..89e84480 --- /dev/null +++ b/frontend/static/css/simditor-markdown.css @@ -0,0 +1,28 @@ +.simditor .markdown-editor { + display: none; +} +.simditor .markdown-editor textarea { + display: block; + width: 100%; + min-height: 200px; + box-sizing: border-box; + padding: 22px 15px 40px; + border: none; + border-bottom: 1px solid #dfdfdf; + resize: none; + outline: none; + font-size: 16px; +} +.simditor.simditor-markdown .markdown-editor { + display: block; +} +.simditor.simditor-markdown .simditor-body { + min-height: 100px; + background: #f3f3f3; +} +.simditor.simditor-markdown .simditor-placeholder { + display: none !important; +} +.simditor .simditor-toolbar .toolbar-item.toolbar-item-markdown .simditor-icon { + font-size: 18px; +} diff --git a/frontend/static/css/simditor.css b/frontend/static/css/simditor.css new file mode 100644 index 00000000..341ae827 --- /dev/null +++ b/frontend/static/css/simditor.css @@ -0,0 +1,746 @@ +/*! +* Simditor v2.3.6 +* http://simditor.tower.im/ +* 2015-12-21 +*/ +@font-face { + font-family: 'Simditor'; + src: url(data:application/font-woff;charset=utf-8;base64,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) format("woff"); + font-weight: normal; + font-style: normal; +} +.simditor-icon { + display: inline-block; + font: normal normal normal 14px/1 'Simditor'; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + transform: translate(0, 0); +} + +.simditor-icon-code:before { + content: '\f000'; +} + +.simditor-icon-bold:before { + content: '\f001'; +} + +.simditor-icon-italic:before { + content: '\f002'; +} + +.simditor-icon-underline:before { + content: '\f003'; +} + +.simditor-icon-times:before { + content: '\f004'; +} + +.simditor-icon-strikethrough:before { + content: '\f005'; +} + +.simditor-icon-list-ol:before { + content: '\f006'; +} + +.simditor-icon-list-ul:before { + content: '\f007'; +} + +.simditor-icon-quote-left:before { + content: '\f008'; +} + +.simditor-icon-table:before { + content: '\f009'; +} + +.simditor-icon-link:before { + content: '\f00a'; +} + +.simditor-icon-picture-o:before { + content: '\f00b'; +} + +.simditor-icon-minus:before { + content: '\f00c'; +} + +.simditor-icon-indent:before { + content: '\f00d'; +} + +.simditor-icon-outdent:before { + content: '\f00e'; +} + +.simditor-icon-unlink:before { + content: '\f00f'; +} + +.simditor-icon-caret-down:before { + content: '\f010'; +} + +.simditor-icon-caret-right:before { + content: '\f011'; +} + +.simditor-icon-upload:before { + content: '\f012'; +} + +.simditor-icon-undo:before { + content: '\f013'; +} + +.simditor-icon-smile-o:before { + content: '\f014'; +} + +.simditor-icon-tint:before { + content: '\f015'; +} + +.simditor-icon-font:before { + content: '\f016'; +} + +.simditor-icon-html5:before { + content: '\f017'; +} + +.simditor-icon-mark:before { + content: '\f018'; +} + +.simditor-icon-align-center:before { + content: '\f019'; +} + +.simditor-icon-align-left:before { + content: '\f01a'; +} + +.simditor-icon-align-right:before { + content: '\f01b'; +} + +.simditor-icon-font-minus:before { + content: '\f01c'; +} + +.simditor-icon-markdown:before { + content: '\f01d'; +} + +.simditor-icon-checklist:before { + content: '\f01e'; +} + +.simditor { + position: relative; + border: 1px solid #c9d8db; +} +.simditor .simditor-wrapper { + position: relative; + background: #ffffff; +} +.simditor .simditor-wrapper > textarea { + display: none !important; + width: 100%; + box-sizing: border-box; + font-family: monaco; + font-size: 16px; + line-height: 1.6; + border: none; + padding: 22px 15px 40px; + min-height: 300px; + outline: none; + background: transparent; + resize: none; +} +.simditor .simditor-wrapper .simditor-placeholder { + display: none; + position: absolute; + left: 0; + z-index: 0; + padding: 22px 15px; + font-size: 16px; + font-family: arial, sans-serif; + line-height: 1.5; + color: #999999; + background: transparent; +} +.simditor .simditor-wrapper.toolbar-floating .simditor-toolbar { + position: fixed; + top: 0; + z-index: 10; + box-shadow: 0 0 6px rgba(0, 0, 0, 0.1); +} +.simditor .simditor-wrapper .simditor-image-loading { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + z-index: 2; +} +.simditor .simditor-wrapper .simditor-image-loading .progress { + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.4); + position: absolute; + bottom: 0; + left: 0; +} +.simditor .simditor-body { + padding: 22px 15px 40px; + min-height: 300px; + outline: none; + cursor: text; + position: relative; + z-index: 1; + background: transparent; +} +.simditor .simditor-body a.selected { + background: #b3d4fd; +} +.simditor .simditor-body a.simditor-mention { + cursor: pointer; +} +.simditor .simditor-body .simditor-table { + position: relative; +} +.simditor .simditor-body .simditor-table.resizing { + cursor: col-resize; +} +.simditor .simditor-body .simditor-table .simditor-resize-handle { + position: absolute; + left: 0; + top: 0; + width: 10px; + height: 100%; + cursor: col-resize; +} +.simditor .simditor-body pre { + /*min-height: 28px;*/ + box-sizing: border-box; + -moz-box-sizing: border-box; + word-wrap: break-word !important; + white-space: pre-wrap !important; +} +.simditor .simditor-body img { + cursor: pointer; +} +.simditor .simditor-body img.selected { + box-shadow: 0 0 0 4px #cccccc; +} +.simditor .simditor-paste-bin { + position: fixed; + bottom: 10px; + right: 10px; + width: 1px; + height: 20px; + font-size: 1px; + line-height: 1px; + overflow: hidden; + padding: 0; + margin: 0; + opacity: 0; + -webkit-user-select: text; +} +.simditor .simditor-toolbar { + border-bottom: 1px solid #eeeeee; + background: #ffffff; + width: 100%; +} +.simditor .simditor-toolbar > ul { + margin: 0; + padding: 0 0 0 6px; + list-style: none; +} +.simditor .simditor-toolbar > ul > li { + position: relative; + display: inline-block; + font-size: 0; +} +.simditor .simditor-toolbar > ul > li > span.separator { + display: inline-block; + background: #cfcfcf; + width: 1px; + height: 18px; + margin: 11px 15px; + vertical-align: middle; +} +.simditor .simditor-toolbar > ul > li > .toolbar-item { + display: inline-block; + width: 46px; + height: 40px; + outline: none; + color: #333333; + font-size: 15px; + line-height: 40px; + vertical-align: middle; + text-align: center; + text-decoration: none; +} +.simditor .simditor-toolbar > ul > li > .toolbar-item span { + opacity: 0.6; +} +.simditor .simditor-toolbar > ul > li > .toolbar-item span.simditor-icon { + display: inline; + line-height: normal; +} +.simditor .simditor-toolbar > ul > li > .toolbar-item:hover span { + opacity: 1; +} +.simditor .simditor-toolbar > ul > li > .toolbar-item.active { + background: #eeeeee; +} +.simditor .simditor-toolbar > ul > li > .toolbar-item.active span { + opacity: 1; +} +.simditor .simditor-toolbar > ul > li > .toolbar-item.disabled { + cursor: default; +} +.simditor .simditor-toolbar > ul > li > .toolbar-item.disabled span { + opacity: 0.3; +} +.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title span:before { + content: "H"; + font-size: 19px; + font-weight: bold; + font-family: 'Times New Roman'; +} +.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title.active-h1 span:before { + content: 'H1'; + font-size: 18px; +} +.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title.active-h2 span:before { + content: 'H2'; + font-size: 18px; +} +.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title.active-h3 span:before { + content: 'H3'; + font-size: 18px; +} +.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-image { + position: relative; + overflow: hidden; +} +.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-image > input[type=file] { + position: absolute; + right: 0px; + top: 0px; + opacity: 0; + font-size: 100px; + cursor: pointer; +} +.simditor .simditor-toolbar > ul > li.menu-on .toolbar-item { + position: relative; + z-index: 20; + background: #ffffff; + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); +} +.simditor .simditor-toolbar > ul > li.menu-on .toolbar-item span { + opacity: 1; +} +.simditor .simditor-toolbar > ul > li.menu-on .toolbar-menu { + display: block; +} +.simditor .simditor-toolbar .toolbar-menu { + display: none; + position: absolute; + top: 40px; + left: 0; + z-index: 21; + background: #ffffff; + text-align: left; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.3); +} +.simditor .simditor-toolbar .toolbar-menu:before { + content: ''; + display: block; + width: 46px; + height: 4px; + background: #ffffff; + position: absolute; + top: -3px; + left: 0; +} +.simditor .simditor-toolbar .toolbar-menu ul { + min-width: 160px; + list-style: none; + margin: 0; + padding: 10px 1px; +} +.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item { + display: block; + font-size: 16px; + line-height: 2em; + padding: 0 10px; + text-decoration: none; + color: #666666; +} +.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item:hover { + background: #f6f6f6; +} +.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h1 { + font-size: 24px; + color: #333333; +} +.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h2 { + font-size: 22px; + color: #333333; +} +.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h3 { + font-size: 20px; + color: #333333; +} +.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h4 { + font-size: 18px; + color: #333333; +} +.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h5 { + font-size: 16px; + color: #333333; +} +.simditor .simditor-toolbar .toolbar-menu ul > li .separator { + display: block; + border-top: 1px solid #cccccc; + height: 0; + line-height: 0; + font-size: 0; + margin: 6px 0; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color { + width: 96px; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list { + height: 40px; + margin: 10px 6px 6px 10px; + padding: 0; + min-width: 0; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li { + float: left; + margin: 0 4px 4px 0; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color { + display: block; + width: 16px; + height: 16px; + background: #dfdfdf; + border-radius: 2px; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color:hover { + opacity: 0.8; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color.font-color-default { + background: #333333; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-1 { + background: #E33737; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-2 { + background: #e28b41; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-3 { + background: #c8a732; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-4 { + background: #209361; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-5 { + background: #418caf; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-6 { + background: #aa8773; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-7 { + background: #999999; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table { + background: #ffffff; + padding: 1px; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table { + border: none; + border-collapse: collapse; + border-spacing: 0; + table-layout: fixed; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table td { + padding: 0; + cursor: pointer; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table td:before { + width: 16px; + height: 16px; + border: 1px solid #ffffff; + background: #f3f3f3; + display: block; + content: ""; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table td.selected:before { + background: #cfcfcf; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-edit-table { + display: none; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-edit-table ul li { + white-space: nowrap; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-image .menu-item-upload-image { + position: relative; + overflow: hidden; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-image .menu-item-upload-image input[type=file] { + position: absolute; + right: 0px; + top: 0px; + opacity: 0; + font-size: 100px; + cursor: pointer; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-alignment { + width: 100%; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-alignment ul { + min-width: 100%; +} +.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-alignment .menu-item { + text-align: center; +} +.simditor .simditor-popover { + display: none; + padding: 5px 8px 0; + background: #ffffff; + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4); + border-radius: 2px; + position: absolute; + z-index: 2; +} +.simditor .simditor-popover .settings-field { + margin: 0 0 5px 0; + font-size: 12px; + height: 25px; + line-height: 25px; +} +.simditor .simditor-popover .settings-field label { + display: inline-block; + margin: 0 5px 0 0; +} +.simditor .simditor-popover .settings-field input[type=text] { + display: inline-block; + width: 200px; + box-sizing: border-box; + font-size: 12px; +} +.simditor .simditor-popover .settings-field input[type=text].image-size { + width: 83px; +} +.simditor .simditor-popover .settings-field .times { + display: inline-block; + width: 26px; + font-size: 12px; + text-align: center; +} +.simditor .simditor-popover.link-popover .btn-unlink, .simditor .simditor-popover.image-popover .btn-upload, .simditor .simditor-popover.image-popover .btn-restore { + display: inline-block; + margin: 0 0 0 5px; + color: #333333; + font-size: 14px; + outline: 0; +} +.simditor .simditor-popover.link-popover .btn-unlink span, .simditor .simditor-popover.image-popover .btn-upload span, .simditor .simditor-popover.image-popover .btn-restore span { + opacity: 0.6; +} +.simditor .simditor-popover.link-popover .btn-unlink:hover span, .simditor .simditor-popover.image-popover .btn-upload:hover span, .simditor .simditor-popover.image-popover .btn-restore:hover span { + opacity: 1; +} +.simditor .simditor-popover.image-popover .btn-upload { + position: relative; + display: inline-block; + overflow: hidden; + vertical-align: middle; +} +.simditor .simditor-popover.image-popover .btn-upload input[type=file] { + position: absolute; + right: 0px; + top: 0px; + opacity: 0; + height: 100%; + width: 28px; +} +.simditor.simditor-mobile .simditor-wrapper.toolbar-floating .simditor-toolbar { + position: absolute; + top: 0; + z-index: 10; + box-shadow: 0 0 6px rgba(0, 0, 0, 0.1); +} + +.simditor .simditor-body, .editor-style { + font-size: 16px; + font-family: arial, sans-serif; + line-height: 1.6; + color: #333; + outline: none; + word-wrap: break-word; +} +.simditor .simditor-body > :first-child, .editor-style > :first-child { + margin-top: 0 !important; +} +.simditor .simditor-body a, .editor-style a { + color: #4298BA; + text-decoration: none; + word-break: break-all; +} +.simditor .simditor-body a:visited, .editor-style a:visited { + color: #4298BA; +} +.simditor .simditor-body a:hover, .editor-style a:hover { + color: #0F769F; +} +.simditor .simditor-body a:active, .editor-style a:active { + color: #9E792E; +} +.simditor .simditor-body a:hover, .simditor .simditor-body a:active, .editor-style a:hover, .editor-style a:active { + outline: 0; +} +.simditor .simditor-body h1, .simditor .simditor-body h2, .simditor .simditor-body h3, .simditor .simditor-body h4, .simditor .simditor-body h5, .simditor .simditor-body h6, .editor-style h1, .editor-style h2, .editor-style h3, .editor-style h4, .editor-style h5, .editor-style h6 { + font-weight: normal; + margin: 40px 0 20px; + color: #000000; +} +.simditor .simditor-body h1, .editor-style h1 { + font-size: 24px; +} +.simditor .simditor-body h2, .editor-style h2 { + font-size: 22px; +} +.simditor .simditor-body h3, .editor-style h3 { + font-size: 20px; +} +.simditor .simditor-body h4, .editor-style h4 { + font-size: 18px; +} +.simditor .simditor-body h5, .editor-style h5 { + font-size: 16px; +} +.simditor .simditor-body h6, .editor-style h6 { + font-size: 16px; +} +.simditor .simditor-body p, .simditor .simditor-body div, .editor-style p, .editor-style div { + word-wrap: break-word; + margin: 0 0 15px 0; + color: #333; + word-wrap: break-word; +} +.simditor .simditor-body b, .simditor .simditor-body strong, .editor-style b, .editor-style strong { + font-weight: bold; +} +.simditor .simditor-body i, .simditor .simditor-body em, .editor-style i, .editor-style em { + font-style: italic; +} +.simditor .simditor-body u, .editor-style u { + text-decoration: underline; +} +.simditor .simditor-body strike, .simditor .simditor-body del, .editor-style strike, .editor-style del { + text-decoration: line-through; +} +.simditor .simditor-body ul, .simditor .simditor-body ol, .editor-style ul, .editor-style ol { + list-style: disc outside none; + margin: 15px 0; + padding: 0 0 0 40px; + line-height: 1.6; +} +.simditor .simditor-body ul ul, .simditor .simditor-body ul ol, .simditor .simditor-body ol ul, .simditor .simditor-body ol ol, .editor-style ul ul, .editor-style ul ol, .editor-style ol ul, .editor-style ol ol { + padding-left: 30px; +} +.simditor .simditor-body ul ul, .simditor .simditor-body ol ul, .editor-style ul ul, .editor-style ol ul { + list-style: circle outside none; +} +.simditor .simditor-body ul ul ul, .simditor .simditor-body ol ul ul, .editor-style ul ul ul, .editor-style ol ul ul { + list-style: square outside none; +} +.simditor .simditor-body ol, .editor-style ol { + list-style: decimal; +} +.simditor .simditor-body blockquote, .editor-style blockquote { + border-left: 6px solid #ddd; + padding: 5px 0 5px 10px; + margin: 15px 0 15px 15px; +} +.simditor .simditor-body blockquote > :first-child, .editor-style blockquote > :first-child { + margin-top: 0; +} +.simditor .simditor-body code, .editor-style code { + display: inline-block; + padding: 0 4px; + margin: 0 5px; + background: #eeeeee; + border-radius: 3px; + font-size: 13px; + font-family: 'monaco', 'Consolas', "Liberation Mono", Courier, monospace; +} +.simditor .simditor-body pre, .editor-style pre { + padding: 10px 5px 10px 10px; + margin: 15px 0; + display: block; + line-height: 18px; + background: #F0F0F0; + border-radius: 3px; + font-size: 13px; + font-family: 'monaco', 'Consolas', "Liberation Mono", Courier, monospace; + white-space: pre; + word-wrap: normal; + overflow-x: auto; +} +.simditor .simditor-body pre code, .editor-style pre code { + display: block; + padding: 0; + margin: 0; + background: none; + border-radius: 0; +} +.simditor .simditor-body hr, .editor-style hr { + display: block; + height: 0px; + border: 0; + border-top: 1px solid #ccc; + margin: 15px 0; + padding: 0; +} +.simditor .simditor-body table, .editor-style table { + width: 100%; + table-layout: fixed; + border-collapse: collapse; + border-spacing: 0; + margin: 15px 0; +} +.simditor .simditor-body table thead, .editor-style table thead { + background-color: #f9f9f9; +} +.simditor .simditor-body table td, .simditor .simditor-body table th, .editor-style table td, .editor-style table th { + min-width: 40px; + height: 30px; + border: 1px solid #ccc; + vertical-align: top; + padding: 2px 4px; + text-align: left; + box-sizing: border-box; +} +.simditor .simditor-body table td.active, .simditor .simditor-body table th.active, .editor-style table td.active, .editor-style table th.active { + background-color: #ffffee; +} +.simditor .simditor-body img, .editor-style img { + margin: 0 5px; + vertical-align: middle; +} diff --git a/frontend/static/css/webuploader.css b/frontend/static/css/webuploader.css new file mode 100644 index 00000000..12f451f8 --- /dev/null +++ b/frontend/static/css/webuploader.css @@ -0,0 +1,28 @@ +.webuploader-container { + position: relative; +} +.webuploader-element-invisible { + position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px,1px,1px,1px); +} +.webuploader-pick { + position: relative; + display: inline-block; + cursor: pointer; + background: #00b7ee; + padding: 10px 15px; + color: #fff; + text-align: center; + border-radius: 3px; + overflow: hidden; +} +.webuploader-pick-hover { + background: #00a2d4; +} + +.webuploader-pick-disable { + opacity: 0.6; + pointer-events:none; +} + diff --git a/utils/shortcuts.py b/utils/shortcuts.py index 9055db81..d0433712 100644 --- a/utils/shortcuts.py +++ b/utils/shortcuts.py @@ -1,12 +1,11 @@ # coding=utf-8 import os import hashlib -import time -import random import logging from django.shortcuts import render from django.core.paginator import Paginator +from django.http import HttpResponseRedirect from rest_framework.response import Response @@ -125,3 +124,7 @@ def build_query_string(kv_data, ignore_none=True): query_string = "?" query_string += (k + "=" + str(v)) return query_string + + +def redirect_to_login(request): + return HttpResponseRedirect("/login/?__from=" + urllib.quote(request.path)) \ No newline at end of file