Просмотр исходного кода

add some config,add upgrade count

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

+ 13 - 2
forums/__init__.py

@@ -6,18 +6,20 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2017-01-25 20:10:50 (CST)
-# Last Update:星期五 2017-3-31 17:37:56 (CST)
+# Last Update:星期日 2017-4-2 12:23:43 (CST)
 #          By:
 # Description:
 # **************************************************************************
 import os
+
 from flask import Flask
+
 from flask_maple.lazy import LazyExtension
 from forums.admin.urls import admin
 
+from .app import register_app
 from .filters import register_jinja2
 from .logs import register_logging
-from .app import register_app
 
 
 def create_app(config):
@@ -28,6 +30,15 @@ def create_app(config):
 
     app = Flask(__name__, template_folder=templates, static_folder=static)
     app.config.from_object(config)
+    if app.config['SUBDOMAIN']['forums']:
+        app.url_map._rules.clear()
+        app.url_map._rules_by_endpoint.clear()
+        app.url_map.default_subdomain = 'forums'
+        app.add_url_rule(
+            app.static_url_path + '/<path:filename>',
+            endpoint='static',
+            view_func=app.send_static_file,
+            subdomain='forums')
     register(app)
     return app
 

+ 12 - 0
forums/api/auth/__init__.py

@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# **************************************************************************
+# Copyright © 2017 jianglin
+# File Name: __init__.py
+# Author: jianglin
+# Email: xiyang0807@gmail.com
+# Created: 2017-04-02 11:48:22 (CST)
+# Last Update:星期日 2017-4-2 11:48:23 (CST)
+#          By:
+# Description:
+# **************************************************************************

+ 5 - 1
forums/api/auth/views.py

@@ -6,7 +6,7 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-10-28 10:26:10 (CST)
-# Last Update:星期六 2017-4-1 21:59:10 (CST)
+# Last Update:星期日 2017-4-2 11:49:2 (CST)
 #          By:
 # Description:
 # **************************************************************************
@@ -24,9 +24,11 @@ from flask_maple.auth.forms import (ForgetForm, LoginForm, RegisterForm,
 from forums.api.user.models import User
 from forums.common.response import HTTPResponse
 from forums.common.serializer import Serializer
+from forums.permission import is_guest
 
 
 class LoginView(MethodView):
+    @is_guest
     def get(self):
         form = LoginForm()
         data = {'form': form}
@@ -62,6 +64,7 @@ class LogoutView(MethodView):
 
 
 class RegisterView(MethodView):
+    @is_guest
     def get(self):
         form = RegisterForm()
         data = {'form': form}
@@ -98,6 +101,7 @@ class RegisterView(MethodView):
 
 
 class ForgetView(MethodView):
+    @is_guest
     def get(self):
         form = ForgetForm()
         data = {'form': form}

+ 1 - 1
forums/api/forums/views.py

@@ -6,7 +6,7 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-12-17 20:45:08 (CST)
-# Last Update:星期四 2017-3-30 14:54:26 (CST)
+# Last Update:星期日 2017-4-2 11:50:57 (CST)
 #          By:
 # Description:
 # **************************************************************************

+ 2 - 1
forums/api/topic/views.py

@@ -6,7 +6,7 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-12-15 22:07:39 (CST)
-# Last Update:星期六 2017-4-1 19:50:27 (CST)
+# Last Update:星期日 2017-4-2 0:23:55 (CST)
 #          By:
 # Description:
 # **************************************************************************
@@ -140,6 +140,7 @@ class TopicView(MethodView):
             'topic': topic,
             'replies': replies
         }
+        topic.read_count = 1
         return render_template('topic/topic.html', **data)
 
     @form_validate(form_board)

+ 4 - 2
forums/api/user/views.py

@@ -6,12 +6,12 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-12-15 22:08:06 (CST)
-# Last Update:星期三 2017-3-29 11:53:37 (CST)
+# Last Update:星期日 2017-4-2 11:51:33 (CST)
 #          By:
 # Description:
 # **************************************************************************
 from flask import redirect, render_template, request, url_for
-from flask_login import current_user
+from flask_login import current_user, login_required
 from forums.api.forums.models import Board
 from forums.api.tag.models import Tags
 from forums.api.topic.models import Topic, Reply
@@ -23,6 +23,7 @@ from .models import User
 
 
 class UserListView(MethodView):
+    @login_required
     def get(self):
         query_dict = request.data
         page, number = self.page_info
@@ -87,6 +88,7 @@ class UserReplyListView(MethodView):
 
 
 class UserFollowerListView(MethodView):
+    @login_required
     def get(self, username):
         user = User.query.filter_by(username=username).first_or_404()
         page, number = self.page_info

+ 1 - 15
forums/common/helper.py

@@ -6,15 +6,13 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-05-20 13:56:43 (CST)
-# Last Update:星期六 2017-3-25 18:56:12 (CST)
+# Last Update:星期六 2017-4-1 23:43:49 (CST)
 #          By:
 # Description:
 # **************************************************************************
 from flask import current_app
 from sqlalchemy import create_engine
 from sqlalchemy.orm import sessionmaker
-from forums.api.forums.models import Board
-from forums.api.topic.forms import TopicForm
 from logging.handlers import SMTPHandler
 from threading import Thread
 
@@ -26,18 +24,6 @@ def db_session():
     return session
 
 
-def form_board():
-    form = TopicForm()
-    results = []
-    for b in Board.query.filter_by(parent_id=None):
-        if b.parent is None:
-            results.append((b.id, b.name))
-        else:
-            results.append((b.id, b.name + '   --' + b.parent.name))
-    form.category.choices = results
-    return form
-
-
 class ThreadedSMTPHandler(SMTPHandler):
     def emit(self, record):
         thread = Thread(target=SMTPHandler.emit, args=(self, record))

+ 11 - 7
forums/count.py

@@ -6,10 +6,11 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2017-03-29 21:28:52 (CST)
-# Last Update:星期六 2017-4-1 22:5:53 (CST)
+# Last Update:星期日 2017-4-2 13:22:19 (CST)
 #          By:
 # Description: 一些统计信息
 # **************************************************************************
+from flask import request
 from .extension import redis_data
 
 
@@ -44,10 +45,13 @@ class Count(object):
     @classmethod
     def topic_read_count(cls, topicId, value=None):
         key = 'count:topic:%s' % str(topicId)
-        if value is not None:
-            pipe = redis_data.pipeline()
-            pipe.hincrby(key, 'read', value)
-            pipe.execute()
+        expire_key = 'expire:topic:read:{}'.format(request.remote_addr)
+        if not redis_data.exists(expire_key):
+            # 设置三分钟之内,阅读次数不增加
+            redis_data.set(expire_key, '1')
+            redis_data.expire(expire_key, 180)
+            if value is not None:
+                redis_data.hincrby(key, 'read', value)
         return redis_data.hget(key, 'read') or 0
 
     @classmethod
@@ -55,9 +59,9 @@ class Count(object):
         key = 'count:reply:%s' % str(replyId)
         if value is not None:
             pipe = redis_data.pipeline()
-            pipe.hincrby(key, 'likers', value)
+            pipe.hincrby(key, 'liker', value)
             pipe.execute()
-        return redis_data.hget(key, 'likers') or 0
+        return redis_data.hget(key, 'liker') or 0
 
     @classmethod
     def user_topic_count(cls, userId, value=None):

+ 2 - 2
forums/docs/templates/docs/doc_list.html

@@ -22,7 +22,7 @@
 </div>
 {%- endmacro %}
 <div class="row">
-    {{ item("Flask-Maple",url_for('docs.doc',path='flask_maple/index.html'),"fa-comments","#F86334")}}
-    {{ item("Flask-Avatar",url_for('docs.doc',path='flask_avatar/index.html'),"fa-book","#F86334")}}
+    {{ item("Flask-Maple",url_for('docs.doc',path='flask-maple/index.html'),"fa-comments","#F86334")}}
+    {{ item("Flask-Avatar",url_for('docs.doc',path='flask-avatar/index.html'),"fa-book","#F86334")}}
 </div>
 {% endblock %}

+ 5 - 2
forums/docs/urls.py

@@ -6,7 +6,7 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2017-01-25 20:14:36 (CST)
-# Last Update:星期三 2017-1-25 20:27:55 (CST)
+# Last Update:星期日 2017-4-2 12:15:40 (CST)
 #          By:
 # Description:
 # **************************************************************************
@@ -14,4 +14,7 @@ from .views import site as docs_site
 
 
 def docs_routers(app):
-    app.register_blueprint(docs_site)
+    if app.config['SUBDOMAIN']['docs']:
+        app.register_blueprint(docs_site, subdomain='docs')
+    else:
+        app.register_blueprint(docs_site, url_prefix='/docs')

+ 3 - 7
forums/docs/views.py

@@ -6,7 +6,7 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-11-09 21:06:32 (CST)
-# Last Update:星期三 2017-3-29 20:32:49 (CST)
+# Last Update:星期日 2017-4-2 12:16:48 (CST)
 #          By:
 # Description:
 # **************************************************************************
@@ -14,11 +14,7 @@ from flask import (Blueprint, render_template, send_from_directory)
 from flask.views import MethodView
 
 site = Blueprint(
-    'docs',
-    __name__,
-    url_prefix='/docs',
-    template_folder='templates',
-    static_folder='static')
+    'docs', __name__, template_folder='templates', static_folder='static')
 
 
 class DocListView(MethodView):
@@ -33,5 +29,5 @@ class DocView(MethodView):
 
 doclist_view = DocListView.as_view('list')
 doc_view = DocView.as_view('doc')
-site.add_url_rule('', view_func=doclist_view)
+site.add_url_rule('/', view_func=doclist_view)
 site.add_url_rule('/<path:path>', view_func=doc_view)

+ 2 - 2
forums/logs.py

@@ -6,7 +6,7 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-11-07 21:43:17 (CST)
-# Last Update:星期四 2016-12-29 21:40:15 (CST)
+# Last Update:星期六 2017-4-1 23:42:40 (CST)
 #          By:
 # Description:
 # **************************************************************************
@@ -53,7 +53,7 @@ def register_logging(app):
     app.logger.addHandler(error_file_handler)
 
     if app.config["SEND_LOGS"]:
-        from common.helper import ThreadedSMTPHandler
+        from .common.helper import ThreadedSMTPHandler
         credentials = (config['MAIL_USERNAME'], config['MAIL_PASSWORD'])
         mailhost = (config['MAIL_SERVER'], config['MAIL_PORT'])
         mail_handler = ThreadedSMTPHandler(

+ 12 - 1
forums/permission.py

@@ -6,7 +6,7 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2017-03-28 16:02:43 (CST)
-# Last Update:星期三 2017-3-29 17:49:46 (CST)
+# Last Update:星期日 2017-4-2 11:47:33 (CST)
 #          By:
 # Description:
 # **************************************************************************
@@ -64,6 +64,17 @@ def is_confirmed(func):
     return _is_confirmed
 
 
+def is_guest(func):
+    @wraps(func)
+    def _is_guest(*args, **kwargs):
+        if not current_user.is_authenticated:
+            return func(*args, **kwargs)
+        flash('你已登陆,请勿重复登陆')
+        return redirect('/')
+
+    return _is_guest
+
+
 class RestfulView(object):
     decorators = ()
 

+ 1 - 2
runserver.py

@@ -6,7 +6,7 @@
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Created: 2016-10-25 22:01:29 (CST)
-# Last Update:星期六 2017-2-18 21:52:8 (CST)
+# Last Update:星期六 2017-4-1 23:10:12 (CST)
 #          By:
 # Description:
 # **************************************************************************
@@ -18,4 +18,3 @@ app.wsgi_app = ProxyFix(app.wsgi_app)
 
 if __name__ == '__main__':
     app.run()
-    print(app.url_map)

+ 28 - 30
templates/maple/footer.html

@@ -18,34 +18,32 @@
  }
 </style>
 <div class="footer col-md-offset-1 col-md-10">
-    <div class="pull-right" style="margin-right:30px;margin-top:10px">
-        <p class="heading text-right">
-            <a href="{{ url_for('forums.help')}}">{{ _('Help')}}</a>
-            <span class="pipe"> | </span>
-            <a href="{{ url_for('forums.about')}}">{{ _('About')}}</a>
-            <span class="pipe"> | </span>
-            <a href="{{ url_for('forums.contact')}}">{{ _('Contact me')}}</a>
-            <span class="pipe"> | </span>
-            <a href="https://github.com/honmaple/maple-bbs" target="_blank">GitHub</a>
-        </p>
-        <p class="text-right hidden-xs" style="font-size:12px;color:#777">
-            {% set footer_count = g.get_online %}
-            <span>{{ _('Now users online:')}}<strong>{{ footer_count[0] }}</strong></span>
-            <span style="margin-left:10px">{{ _('Registered users online:') }}<strong>{{ footer_count[1] }}</strong></span>
-            <span style="margin-left:10px">{{ _('Guests online:')}}<strong>{{ footer_count[2] }}</strong></span>
-        </p>
-        <p class="text-right  hidden-xs"  style="font-size:12px;color:#777">
-            <span>{{ show_time() }}</span>
-            <span style="margin-left:10px">{{ _('Highest online:')}}<strong>{{ footer_count[3] }}</strong></span>
-            <span style="margin-left:10px">{{ _('Time of highest online:')}}<strong>{{ footer_count[4] }}</strong></span>
-        </p>
-    </div>
-    <div style="font-size:13px;margin-top:10px;">
-        <blockquote>
-            <p style="font-size:14px;">{{ _(SITE['description']) }}</p>
-            <footer>
-                <span> Copyright © 2015-2016 honmaple.</span>
-            </footer>
-        </blockquote>
-    </div>
+  <div class="pull-right" style="margin-right:30px;margin-top:10px">
+    <p class="heading text-right">
+      <a href="{{ url_for('forums.help')}}">{{ _('Help')}}</a>
+      <span class="pipe"> | </span>
+      <a href="{{ url_for('forums.about')}}">{{ _('About')}}</a>
+      <span class="pipe"> | </span>
+      <a href="{{ url_for('forums.contact')}}">{{ _('Contact me')}}</a>
+      <span class="pipe"> | </span>
+      <a href="https://github.com/honmaple/maple-bbs" target="_blank">GitHub</a>
+    </p>
+    <p class="text-right hidden-xs" style="font-size:12px;color:#777">
+      {% set footer_count = g.get_online %}
+      <span>{{ _('Now users online:')}}<strong>{{ footer_count[0] }}</strong></span>
+      <span style="margin-left:10px">{{ _('Registered users online:') }}<strong>{{ footer_count[1] }}</strong></span>
+      <span style="margin-left:10px">{{ _('Guests online:')}}<strong>{{ footer_count[2] }}</strong></span>
+    </p>
+    <p class="text-right hidden-xs" style="font-size:12px;color:#777">
+      <span>{{ show_time() }}</span>
+      <span style="margin-left:10px">{{ _('Highest online:')}}<strong>{{ footer_count[3] }}</strong></span>
+      <span style="margin-left:10px">{{ _('Time of highest online:')}}<strong>{{ footer_count[4] }}</strong></span>
+    </p>
+  </div>
+  <blockquote>
+    <p style="font-size:14px;">{{ _(SITE['description']) }}</p>
+    <footer>
+      <span> Copyright © 2015-2016 honmaple.</span>
+    </footer>
+  </blockquote>
 </div>

+ 85 - 0
upgrade_coount.py

@@ -0,0 +1,85 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# **************************************************************************
+# Copyright © 2017 jianglin
+# File Name: upgrade_coount.py
+# Author: jianglin
+# Email: xiyang0807@gmail.com
+# Created: 2017-04-02 13:00:02 (CST)
+# Last Update:星期日 2017-4-2 13:47:2 (CST)
+#          By:
+# Description:
+# **************************************************************************
+from runserver import app
+from forums.api.topic.models import Topic, Reply
+from forums.api.forums.models import Board
+from forums.api.user.models import User
+from forums.extension import redis_data
+
+
+def topic():
+    topics = Topic.query.all()
+    for t in topics:
+        print('topic', t.title)
+        key = 'count:topic:{}'.format(t.id)
+        reply_count = t.replies.count()
+        read_key = 'topic:{}'.format(t.id)
+        read_count = redis_data.hget(read_key, 'read')
+        if reply_count:
+            redis_data.hset(key, 'replies', reply_count)
+        if read_count:
+            redis_data.hset(key, 'read', read_count)
+        # 删除旧key
+        redis_data.delete(read_key)
+
+
+def reply():
+    replies = Reply.query.all()
+    for t in replies:
+        print('reply', t.id)
+        key = 'count:reply:{}'.format(t.id)
+        liker_count = t.likers.count()
+        if liker_count:
+            redis_data.hset(key, 'liker', liker_count)
+
+
+def user():
+    users = User.query.all()
+    for t in users:
+        print('user', t.username)
+        key = 'count:user:{}'.format(t.id)
+        topic_count = t.topics.count()
+        reply_count = t.replies.count()
+        if topic_count:
+            redis_data.hset(key, 'topic', topic_count)
+        if reply_count:
+            redis_data.hset(key, 'replies', topic_count)
+        # 删除旧key
+        old_user_key = 'user:{}'.format(t.id)
+        redis_data.delete(old_user_key)
+
+
+def board():
+    boards = Board.query.all()
+    for b in boards:
+        print('board', b.name)
+        key = 'count:board:{}'.format(b.id)
+        topic_count = Topic.query.filter_by(board_id=b.id).count()
+        reply_count = Reply.query.filter_by(topic__board_id=b.id).count()
+        post_count = topic_count + reply_count
+        if topic_count:
+            redis_data.hset(key, 'topic', topic_count)
+        if post_count:
+            redis_data.hset(key, 'post', topic_count)
+
+
+def main():
+    with app.app_context():
+        topic()
+        board()
+        user()
+        reply()
+
+
+if __name__ == '__main__':
+    main()