honmaple 8 лет назад
Родитель
Сommit
fa34fe6541

+ 2 - 2
src/api/board/urls.py

@@ -6,7 +6,7 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-12-15 22:28:28 (CST)
-# Last Update:星期四 2016-12-22 22:47:31 (CST)
+# Last Update:星期三 2017-1-25 21:54:40 (CST)
 #          By:
 # Description:
 # **************************************************************************
@@ -19,6 +19,6 @@ board_list = BoardListView.as_view('list')
 board = BoardView.as_view('board')
 forums = BoardListView.as_view('forums')
 
-site.add_url_rule('/forums', view_func=board_list)
 site.add_url_rule('/index', view_func=forums)
+site.add_url_rule('/forums', view_func=board_list)
 site.add_url_rule('/forums/<int:boardId>', view_func=board)

+ 13 - 38
src/api/board/views.py

@@ -6,58 +6,33 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-12-15 22:04:05 (CST)
-# Last Update:星期三 2017-1-25 20:25:9 (CST)
+# Last Update:星期三 2017-1-25 22:0:46 (CST)
 #          By:
 # Description:
 # **************************************************************************
 from flask import request, render_template
-from flask.views import MethodView
-from flask_maple.serializer import FlaskSerializer as Serializer
-from flask_maple.response import HTTPResponse
-from common.views import ViewListMixin
+from common.views import BaseMethodView as MethodView
 from .models import Board
+from api.topic.models import Topic
 
 
-class BoardListView(MethodView, ViewListMixin):
+class BoardListView(MethodView):
     def get(self):
         page, number = self.page_info
         boards = Board.get_list(page, number)
-        return render_template('board/board_list.html', boards=boards)
-        # serializer = Serializer(boards, many=True)
-        # return HTTPResponse(HTTPResponse.NORMAL_STATUS,
-        #                     **serializer.data).to_response()
-
-    def post(self):
-        post_data = request.data
-        name = post_data.pop('name', None)
-        description = post_data.pop('description', None)
-        parents = post_data.pop('parents', None)
-        children = post_data.pop('children', None)
-        board = Board(name=name, description=description)
-        if parents is not None:
-            parent_boards = Board.query.filter_by(id__in=parents)
-            board.parents += parent_boards
-        if children is not None:
-            child_boards = Board.query.filter_by(id__in=children)
-            board.children += child_boards
-        board.save()
-        serializer = Serializer(board, many=False)
-        return HTTPResponse(HTTPResponse.NORMAL_STATUS,
-                            **serializer.data).to_response()
+        data = {'title': 'Board', 'boards': boards}
+        return render_template('board/board_list.html', **data)
 
 
 class BoardView(MethodView):
     def get(self, boardId):
         board = Board.get(id=boardId)
-        topics = board.topics.all()
-        data = {'board': board, 'topics': topics}
+        topics = self.topics(boardId)
+        data = {'title': 'Board', 'board': board, 'topics': topics}
         return render_template('board/board.html', **data)
-        # serializer = Serializer(user, many=False)
-        # return HTTPResponse(
-        #     HTTPResponse.NORMAL_STATUS, data=serializer.data).to_response()
-
-    def put(self, boardId):
-        return 'put'
 
-    def delete(self, boardId):
-        return 'delete'
+    def topics(self, boardId):
+        page, number = self.page_info
+        filter_dict = dict(board_id=boardId)
+        topics = Topic.get_list(page, number, filter_dict)
+        return topics

+ 6 - 7
src/api/follow/views.py

@@ -6,20 +6,19 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-12-22 21:49:05 (CST)
-# Last Update:星期四 2016-12-29 21:18:30 (CST)
+# Last Update:星期三 2017-1-25 21:48:45 (CST)
 #          By:
 # Description:
 # **************************************************************************
-from flask.views import MethodView
 from flask import (render_template, request, redirect, url_for, jsonify,
                    current_app)
 from flask_login import current_user
-from common.views import ViewListMixin
+from common.views import BaseMethodView as MethodView
 from api.tag.models import Tags
 from api.topic.models import Topic, Collect
 
 
-class FollowingTagsView(MethodView, ViewListMixin):
+class FollowingTagsView(MethodView):
     def get(self):
         page, number = self.page_info
         filter_dict = {'followers__username': current_user.username}
@@ -28,7 +27,7 @@ class FollowingTagsView(MethodView, ViewListMixin):
         return render_template('follow/following_tags.html', **data)
 
 
-class FollowingTopicsView(MethodView, ViewListMixin):
+class FollowingTopicsView(MethodView):
     def get(self):
         page, number = self.page_info
         filter_dict = {'followers__username': current_user.username}
@@ -37,7 +36,7 @@ class FollowingTopicsView(MethodView, ViewListMixin):
         return render_template('follow/following_topics.html', **data)
 
 
-class FollowingUsersView(MethodView, ViewListMixin):
+class FollowingUsersView(MethodView):
     def get(self):
         page, number = self.page_info
         users = current_user.following_users.paginate(page, number, True)
@@ -45,7 +44,7 @@ class FollowingUsersView(MethodView, ViewListMixin):
         return render_template('follow/following_users.html', **data)
 
 
-class FollowingCollectsView(MethodView, ViewListMixin):
+class FollowingCollectsView(MethodView):
     def get(self):
         page, number = self.page_info
         filter_dict = {'followers__username': current_user.username}

+ 7 - 8
src/api/mine/views.py

@@ -6,19 +6,18 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-12-21 22:08:37 (CST)
-# Last Update:星期四 2016-12-29 21:18:30 (CST)
+# Last Update:星期三 2017-1-25 21:48:26 (CST)
 #          By:
 # Description:
 # **************************************************************************
 from flask import render_template, g, redirect, url_for
-from flask.views import MethodView
+from common.views import BaseMethodView as MethodView
 from api.topic.models import Topic, Collect
 from api.reply.models import Reply
 from api.user.models import User
-from common.views import ViewListMixin
 
 
-class UserTopicListView(MethodView, ViewListMixin):
+class UserTopicListView(MethodView):
     def get(self):
         username = g.username
         page, number = self.page_info
@@ -29,7 +28,7 @@ class UserTopicListView(MethodView, ViewListMixin):
         return render_template('mine/topic_list.html', **data)
 
 
-class UserReplyListView(MethodView, ViewListMixin):
+class UserReplyListView(MethodView):
     def get(self):
         username = g.username
         page, number = self.page_info
@@ -40,7 +39,7 @@ class UserReplyListView(MethodView, ViewListMixin):
         return render_template('mine/reply_list.html', **data)
 
 
-class UserCollectListView(MethodView, ViewListMixin):
+class UserCollectListView(MethodView):
     def get(self):
         username = g.username
         page, number = self.page_info
@@ -51,7 +50,7 @@ class UserCollectListView(MethodView, ViewListMixin):
         return render_template('mine/collect_list.html', **data)
 
 
-class UserFollowerListView(MethodView, ViewListMixin):
+class UserFollowerListView(MethodView):
     def get(self):
         username = g.username
         user = User.get(username=username)
@@ -61,7 +60,7 @@ class UserFollowerListView(MethodView, ViewListMixin):
         return render_template('mine/follower_list.html', **data)
 
 
-class UserFollowingListView(MethodView, ViewListMixin):
+class UserFollowingListView(MethodView):
     def get(self):
         return redirect(url_for('follow.topic'))
         # username = g.username

+ 3 - 4
src/api/permission/views.py

@@ -6,18 +6,17 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-12-17 09:31:49 (CST)
-# Last Update:星期三 2017-1-25 20:25:9 (CST)
+# Last Update:星期三 2017-1-25 21:46:14 (CST)
 #          By:
 # Description:
 # **************************************************************************
-from flask.views import MethodView
 from flask_maple.serializer import FlaskSerializer as Serializer
 from flask_maple.response import HTTPResponse
-from common.views import ViewListMixin
+from common.views import BaseMethodView as MethodView
 from .models import Group
 
 
-class GroupListView(MethodView, ViewListMixin):
+class GroupListView(MethodView):
     def get(self):
         page, number = self.page_info
         users = Group.get_list(page, number)

+ 3 - 4
src/api/reply/views.py

@@ -6,17 +6,16 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-12-15 22:06:39 (CST)
-# Last Update:星期三 2017-1-25 20:25:9 (CST)
+# Last Update:星期三 2017-1-25 21:47:19 (CST)
 #          By:
 # Description:
 # **************************************************************************
 from flask import request, render_template, g, redirect
-from flask.views import MethodView
 from flask_maple.serializer import FlaskSerializer as Serializer
 from flask_maple.response import HTTPResponse
 from flask_maple.auth.forms import form_validate
 from flask_login import current_user
-from common.views import ViewListMixin
+from common.views import BaseMethodView as MethodView
 from .models import Reply
 from .forms import ReplyForm
 
@@ -25,7 +24,7 @@ def error_callback():
     return redirect('/')
 
 
-class ReplyListView(MethodView, ViewListMixin):
+class ReplyListView(MethodView):
     def get(self):
         form = ReplyForm()
         page, number = self.page_info

+ 5 - 14
src/api/tag/views.py

@@ -6,15 +6,14 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-12-15 22:07:04 (CST)
-# Last Update:星期三 2017-1-25 20:25:9 (CST)
+# Last Update:星期三 2017-1-25 21:47:45 (CST)
 #          By:
 # Description:
 # **************************************************************************
 from flask import request, url_for, current_app, render_template
-from flask.views import MethodView
 from flask_maple.serializer import FlaskSerializer as Serializer
 from flask_maple.response import HTTPResponse
-from common.views import ViewListMixin
+from common.views import BaseMethodView as MethodView
 from api.topic.models import Topic
 from .models import Tags
 from urllib.parse import urljoin
@@ -22,7 +21,7 @@ from werkzeug.utils import escape
 from werkzeug.contrib.atom import AtomFeed
 
 
-class TagsListView(MethodView, ViewListMixin):
+class TagsListView(MethodView):
     per_page = 99
 
     def get(self):
@@ -33,24 +32,16 @@ class TagsListView(MethodView, ViewListMixin):
         # return HTTPResponse(HTTPResponse.NORMAL_STATUS,
         #                     **serializer.data).to_response()
 
-    def post(self):
-        return 'post'
-
 
 class TagsView(MethodView):
     def get(self, name):
         tag = Tags.get(name=name)
-        return render_template('tag/tag.html', tag=tag)
+        data = {'title': tag.name, 'tag': tag}
+        return render_template('tag/tag.html', **data)
         # serializer = Serializer(user, many=False)
         # return HTTPResponse(
         #     HTTPResponse.NORMAL_STATUS, data=serializer.data).to_response()
 
-    def put(self, name):
-        return 'put'
-
-    def delete(self, name):
-        return 'delete'
-
 
 class TagFeedView(MethodView):
     def get(self, name):

+ 1 - 1
src/api/topic/models.py

@@ -6,7 +6,7 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-12-15 20:52:07 (CST)
-# Last Update:星期三 2017-1-25 20:25:8 (CST)
+# Last Update:星期三 2017-1-25 21:56:8 (CST)
 #          By:
 # Description:
 # **************************************************************************

+ 4 - 5
src/api/topic/views.py

@@ -6,12 +6,11 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-12-15 22:07:39 (CST)
-# Last Update:星期三 2017-1-25 20:25:8 (CST)
+# Last Update:星期三 2017-1-25 21:47:3 (CST)
 #          By:
 # Description:
 # **************************************************************************
 from flask import request, render_template, redirect, url_for
-from flask.views import MethodView
 from flask_maple.serializer import FlaskSerializer as Serializer
 from flask_maple.response import HTTPResponse
 from flask_maple.auth.forms import form_validate
@@ -19,7 +18,7 @@ from flask_login import current_user
 from flask_babelex import gettext as _
 from api.board.models import Board
 from api.tag.models import Tags
-from common.views import ViewListMixin
+from common.views import BaseMethodView as MethodView
 from common.helper import form_board
 from .models import Topic, Collect
 from .forms import (TopicForm, ReplyForm, CollectForm, error_callback,
@@ -57,7 +56,7 @@ class TopicPreviewView(MethodView):
         return
 
 
-class TopicListView(MethodView, ViewListMixin):
+class TopicListView(MethodView):
     @property
     def filter_dict(self):
         _dict = {}
@@ -145,7 +144,7 @@ class TopicView(MethodView):
                             **serializer.data).to_response()
 
 
-class CollectListView(MethodView, ViewListMixin):
+class CollectListView(MethodView):
     def get(self):
         form = CollectForm()
         page, number = self.page_info

+ 3 - 4
src/api/user/views.py

@@ -6,19 +6,18 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-12-15 22:08:06 (CST)
-# Last Update:星期三 2017-1-25 20:25:9 (CST)
+# Last Update:星期三 2017-1-25 21:45:53 (CST)
 #          By:
 # Description:
 # **************************************************************************
 from flask import render_template, redirect, url_for
-from flask.views import MethodView
 from flask_maple.serializer import FlaskSerializer as Serializer
 from flask_maple.response import HTTPResponse
-from common.views import ViewListMixin
+from common.views import BaseMethodView as MethodView
 from .models import User
 
 
-class UserListView(MethodView, ViewListMixin):
+class UserListView(MethodView):
     def get(self):
         page, number = self.page_info
         users = User.get_list(page, number)

+ 55 - 0
src/common/models.py

@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# **************************************************************************
+# Copyright © 2017 jianglin
+# File Name: models.py
+# Author: jianglin
+# Email: xiyang0807@gmail.com
+# Created: 2017-01-25 21:33:09 (CST)
+# Last Update:星期三 2017-1-25 21:33:42 (CST)
+#          By:
+# Description:
+# **************************************************************************
+from forums.extension import db
+from sqlalchemy.ext.declarative import declared_attr
+from datetime import datetime
+from flask_maple.models import ModelMixin
+
+
+class CommonMixin(ModelMixin):
+    @declared_attr
+    def id(cls):
+        return db.Column(db.Integer, primary_key=True)
+
+
+class CommonTimeMixin(CommonMixin):
+    @declared_attr
+    def created_at(cls):
+        return db.Column(db.DateTime, default=datetime.utcnow())
+
+    @declared_attr
+    def updated_at(cls):
+        return db.Column(
+            db.DateTime, default=datetime.utcnow(), onupdate=datetime.utcnow())
+
+
+class CommonUserMixin(CommonTimeMixin):
+    @declared_attr
+    def user_id(cls):
+        return db.Column(
+            db.Integer, db.ForeignKey(
+                'user.id', ondelete="CASCADE"))
+
+    @declared_attr
+    def user(cls):
+        name = cls.__name__.lower()
+        if not name.endswith('s'):
+            name = name + 's'
+        if hasattr(cls, 'user_related_name'):
+            name = cls.user_related_name
+        return db.relationship(
+            'User',
+            backref=db.backref(
+                name, cascade='all,delete', lazy='dynamic'),
+            uselist=False,
+            lazy='joined')

+ 5 - 2
src/common/response.py

@@ -6,7 +6,7 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-10-25 21:07:00 (CST)
-# Last Update:星期六 2016-12-17 10:38:49 (CST)
+# Last Update:星期三 2017-1-25 21:43:35 (CST)
 #          By:
 # Description:
 # **************************************************************************
@@ -27,6 +27,8 @@ class HTTPResponse(object):
 
     FORBIDDEN = '403'
 
+    OTHER_ERROR = '500'
+
     STATUS_DESCRIPTION = {
         NORMAL_STATUS: 'normal',
         AUTH_USER_OR_PASSWORD_ERROR: _('Username or Password Error'),
@@ -39,7 +41,8 @@ class HTTPResponse(object):
         AUTH_TOKEN_VERIFY_FAIL:
         _('Token is out of time,please get token again!'),
         FORM_VALIDATE_ERROR: _('Form validate error'),
-        FORBIDDEN: _('You have no permission!')
+        FORBIDDEN: _('You have no permission!'),
+        OTHER_ERROR: _('Other error')
     }
 
     def __init__(self,

+ 36 - 0
src/common/utils.py

@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# **************************************************************************
+# Copyright © 2017 jianglin
+# File Name: utils.py
+# Author: jianglin
+# Email: xiyang0807@gmail.com
+# Created: 2017-01-25 21:39:41 (CST)
+# Last Update:星期三 2017-1-25 21:43:0 (CST)
+#          By:
+# Description:
+# **************************************************************************
+import traceback
+import logging
+from functools import wraps
+from .response import HTTPResponse
+
+logger = logging.getLogger("logg")
+
+
+def log_exception(func):
+    @wraps(func)
+    def wrapper(*args, **kwargs):
+        try:
+            logger.info(str(args))
+            logger.info(str(kwargs))
+            result = func(*args, **kwargs)
+            return result
+        except Exception as e:
+            error = traceback.format_exc()
+            logger.info(u"cache unhanld exception%s ", error)
+            return HTTPResponse(
+                HTTPResponse.OTHER_ERROR,
+                description=u"捕获到未处理的异常,%s" % error).to_response()
+
+    return wrapper

+ 24 - 9
src/common/views.py

@@ -6,33 +6,48 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-10-25 20:57:36 (CST)
-# Last Update:星期四 2016-12-29 20:54:44 (CST)
+# Last Update:星期三 2017-1-25 21:55:25 (CST)
 #          By:
 # Description:
 # **************************************************************************
 from flask import (current_app, request)
+from flask.views import MethodView
+from flask_login import login_required
+from .utils import log_exception
 
-__all__ = ['ViewListMixin']
 
+class BaseMethodView(MethodView):
+    # @log_exception
+    def dispatch_request(self, *args, **kwargs):
+        return super(BaseMethodView, self).dispatch_request(*args, **kwargs)
 
-class ViewListMixin(object):
     @property
     def page_info(self):
         page = request.args.get('page', 1, type=int)
         if hasattr(self, 'per_page'):
             per_page = getattr(self, 'per_page')
-            number = request.args.get('number', per_page, type=int)
         else:
             per_page = current_app.config.setdefault('PER_PAGE', 20)
-            number = request.args.get('number', per_page, type=int)
+
+        number = request.args.get('number', per_page, type=int)
         if number > 100:
             number = current_app.config['PER_PAGE']
         return page, number
 
-    @property
-    def filter_dict(self):
+    def filter_dict(self, model):
         return {}
 
-    @property
-    def order_by(self):
+    def order_by(self, model):
         return ()
+
+
+class IsAuthMethodView(BaseMethodView):
+    decorators = [login_required]
+
+
+class IsAdminMethodView(BaseMethodView):
+    decorators = [login_required]
+
+
+class IsSuperAdminMethodView(BaseMethodView):
+    decorators = [login_required]

BIN
src/forums/test.db


+ 10 - 0
src/templates/base/base.html

@@ -4,6 +4,16 @@
 {% import 'base/link.html' as link %}
 {% import 'base/panel.html' as panel_base %}
 {% from 'base/head.html' import breadcrumb %}
+{% block script -%}
+{{ super() }}
+<script type="text/javascript" src="{{ url_for('static',filename='assets/home.js')}}"></script>
+{%- endblock script %}
+
+{% block style -%}
+{{ super() }}
+<link rel="stylesheet" href="{{ url_for('static',filename='assets/home.css')}}" type="text/css" media="screen" />
+{%- endblock style %}
+
 {% block main %}
 {% include "base/header.html" %}
 <div class="col-md-offset-1 col-md-10" style="padding:0;margin-top:60px">

+ 1 - 1
src/templates/board/board.html

@@ -15,7 +15,7 @@
         </div>
         <div class="panel panel-default">
             {{ topic_form() }}
-            {% for topic in topics %}
+            {% for topic in topics.items %}
             {{ topic_body(topic) }}
             {% else %}
             {{ no_topics() }}

+ 3 - 0
src/templates/forums/index.html

@@ -3,6 +3,7 @@
 {% from 'forums/_macro.html' import forums_title,forums_item %}
 {% from 'topic/_list_macro.html' import form as topic_form %}
 {% from 'topic/_list_macro.html' import body as topic_body %}
+{% from 'topic/_list_macro.html' import no_topics %}
 {{ breadcrumb() }}
 {{ forums_title() }}
 <div class="row hidden-sm hidden-xs">
@@ -17,6 +18,8 @@
             {{ topic_form() }}
             {% for topic in topics.items %}
             {{ topic_body(topic) }}
+            {% else %}
+            {{ no_topics() }}
             {% endfor %}
             <div class="panel-footer clearfix">
                 <a class="pull-right" href="{{ url_for('topic.good')}}">

+ 0 - 2
src/templates/tag/tag.html

@@ -11,8 +11,6 @@
             <div class="panel-body" style="border-bottom: 1px solid #ddd;">
                 {{ title(tag) }}
             </div>
-        </div>
-        <div class="panel panel-default">
             {{ topic_form() }}
             {% for topic in tag.topics %}
             {{ topic_body(topic) }}