Browse Source

fix tag related_tags add forums count

修复相关节点的bug,增加社区统计(包括用户,主题等)
honmaple 8 years ago
parent
commit
5a69483beb

+ 20 - 32
README.org

@@ -1,4 +1,4 @@
-* Honmaple(maplebb)
+* Honmaple
 
 
   [[license][https://img.shields.io/badge/license-GPL3.0-blue.svg]]
   [[license][https://img.shields.io/badge/license-GPL3.0-blue.svg]]
 
 
@@ -7,6 +7,16 @@
   [[https://raw.githubusercontent.com/honmaple/maple-bbs/master/screenshooter/ask.png]]
   [[https://raw.githubusercontent.com/honmaple/maple-bbs/master/screenshooter/ask.png]]
 
 
   This is a free,open-source forums system based on the flask
   This is a free,open-source forums system based on the flask
+  
+  *If you have used honmaple before 2017-4-1,please use upgrade script to upgrade data*
+  
+  *important !* : please modify script to configure as your own database.
+  #+BEGIN_SRC sh
+  # session1:old database
+  # session2:new database
+  python upgrade.py
+  python upgrade_count.py
+  #+END_SRC
 
 
 ** Features
 ** Features
    + Register & login & forget password
    + Register & login & forget password
@@ -18,7 +28,6 @@
    + Choice markdown to ask
    + Choice markdown to ask
    + Tags rss
    + Tags rss
    + Avatar
    + Avatar
-   + Topic vote
      
      
 ** Installation
 ** Installation
 
 
@@ -31,11 +40,10 @@
     Beacause flask_maple.rbac isn't uploaded to pypi
     Beacause flask_maple.rbac isn't uploaded to pypi
     you should 
     you should 
     #+BEGIN_SRC shell
     #+BEGIN_SRC shell
-git clone https://github.com/honmaple/flask-maple
-cd flask-maple
-git checkout develop
-pip uninstall flask-maple
-python setup.py install
+      git clone https://github.com/honmaple/flask-maple
+      cd flask-maple
+      pip uninstall flask-maple
+      python setup.py install
     #+END_SRC
     #+END_SRC
     to install flask-maple
     to install flask-maple
 
 
@@ -43,29 +51,6 @@ python setup.py install
     #+BEGIN_SRC shell
     #+BEGIN_SRC shell
     mv config.example config
     mv config.example config
     #+END_SRC
     #+END_SRC
-    after finished configure
-
-    *For Production*
-    Please set DEBUG = False or change *maple/__init__.py*
-    #+BEGIN_SRC python
-    app.config.from_object('config.config')
-    #+END_SRC
-    to
-    #+BEGIN_SRC python
-    app.config.from_object('config.production')
-    #+END_SRC
-
-
-*** Comment before init db
-
-    place of file: *maple/topic/forms.py*
-    #+BEGIN_SRC python
-    category = SelectField(
-        _('Category:'),
-        choices=[(b.id, b.board + '   --' + b.parent_board)
-                 for b in Board.query.all()],
-        coerce=int)
-    #+END_SRC
 
 
 *** Init sql
 *** Init sql
     #+BEGIN_SRC python
     #+BEGIN_SRC python
@@ -73,11 +58,14 @@ python setup.py install
     python manager.py db migrate -m "first migrate"
     python manager.py db migrate -m "first migrate"
     python manager.py db upgrade
     python manager.py db upgrade
     #+END_SRC
     #+END_SRC
-    *Ok*,please recovery *maple/topic/forms.py*
+    Or
+    #+BEGIN_SRC sh
+    python manager.py init_db
+    #+END_SRC
 
 
 *** Create admin account
 *** Create admin account
     #+BEGIN_SRC shell
     #+BEGIN_SRC shell
-python manager.py create_user
+    python manager.py create_user
     #+END_SRC
     #+END_SRC
 
 
 *** Login and visit admin 
 *** Login and visit admin 

+ 85 - 0
config.example

@@ -0,0 +1,85 @@
+#!/usr/bin/env python
+# -*- coding=UTF-8 -*-
+# **************************************************************************
+# Copyright © 2016 jianglin
+# File Name: config.py
+# Author: jianglin
+# Email: xiyang0807@gmail.com
+# Created: 2016-05-20 12:31:46 (CST)
+# Last Update:星期日 2017-4-2 15:39:4 (CST)
+#          By: jianglin
+# Description:
+# **************************************************************************
+from datetime import timedelta
+from os import path, pardir
+
+DEBUG = True
+SECRET_KEY = 'secret key'
+SECURITY_PASSWORD_SALT = 'you will never guess'
+SECRET_KEY_SALT = 'you will never guess'
+
+# avatar upload directory
+AVATAR_FOLDER = path.join(path.abspath(path.dirname(__file__)), 'avatar')
+# avatar generate range
+AVATAR_RANGE = [122, 512]
+
+# for development use localhost:5000
+# for production use xxx.com
+# SERVER_NAME = 'localhost:5000'
+
+# remember me to save cookies
+PERMANENT_SESSION_LIFETIME = timedelta(days=3)
+REMEMBER_COOKIE_DURATION = timedelta(days=3)
+ONLINE_LAST_MINUTES = 5
+
+# You want show how many topics per page
+PER_PAGE = 12
+
+# Use cache
+CACHE_TYPE = 'null'
+CACHE_DEFAULT_TIMEOUT = 60
+CACHE_KEY_PREFIX = 'cache:'
+CACHE_REDIS_HOST = '127.0.0.1'
+CACHE_REDIS_PORT = '6379'
+CACHE_REDIS_PASSWORD = 'your password'
+CACHE_REDIS_DB = 2
+
+# Redis setting
+REDIS = {'db': 1, 'password': 'your password', 'decode_responses': True}
+
+# some middleware
+MIDDLEWARE = ['forums.common.middleware.GlobalMiddleware',
+              'forums.common.middleware.OnlineMiddleware']
+
+# Mail such as qq
+MAIL_SERVER = 'smtp.qq.com'
+MAIL_PORT = 25
+MAIL_USE_TLS = True
+MAIL_USE_SSL = False
+MAIL_USERNAME = "your email"
+MAIL_PASSWORD = "your password"
+MAIL_DEFAULT_SENDER = 'your email'
+# MAIL_SUPPRESS_SEND = True
+
+# Log,if SEND_LOGS is True when web app has some error happen(500)
+# the email will be sent to RECEIVER
+SEND_LOGS = True
+RECEIVER = ["yourname@gmail.com"]
+INFO_LOG = "info.log"
+ERROR_LOG = "error.log"
+SERVER_NAME = 'localhost:5000'
+SUBDOMAIN = {'forums': True, 'docs': True}
+
+# Sql
+SQLALCHEMY_DATABASE_URI = 'postgresql://postgres:password@localhost/your_db'
+WHOOSH_BASE = 'search.db'
+# SQLALCHEMY_ECHO = True
+# SQLALCHEMY_DATABASE_URI = 'sqlite:///test.db'
+# SQLALCHEMY_DATABASE_URI = 'mysql://username:password@server/db'
+
+# avatar upload folder
+AVATAR_FOLDER = 'avatars/'
+
+# Locale
+LANGUAGES = {'en': 'English', 'zh': 'Chinese'}
+SITE = {'title': 'Honmaple', 'description': '爱生活,更爱自由', 'avatar': ''}

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

@@ -6,7 +6,7 @@
 # Author: jianglin
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Email: xiyang0807@gmail.com
 # Created: 2016-10-28 10:26:10 (CST)
 # Created: 2016-10-28 10:26:10 (CST)
-# Last Update:星期日 2017-4-2 11:49:2 (CST)
+# Last Update:星期日 2017-4-2 15:25:52 (CST)
 #          By:
 #          By:
 # Description:
 # Description:
 # **************************************************************************
 # **************************************************************************
@@ -25,6 +25,7 @@ from forums.api.user.models import User
 from forums.common.response import HTTPResponse
 from forums.common.response import HTTPResponse
 from forums.common.serializer import Serializer
 from forums.common.serializer import Serializer
 from forums.permission import is_guest
 from forums.permission import is_guest
+from forums.count import Count
 
 
 
 
 class LoginView(MethodView):
 class LoginView(MethodView):
@@ -88,6 +89,7 @@ class RegisterView(MethodView):
         user.set_password(password)
         user.set_password(password)
         user.save()
         user.save()
         login_user(user)
         login_user(user)
+        Count.forums_user_count(1)
         self.email(user)
         self.email(user)
         return HTTPResponse(HTTPResponse.NORMAL_STATUS).to_response()
         return HTTPResponse(HTTPResponse.NORMAL_STATUS).to_response()
 
 

+ 9 - 1
forums/api/tag/models.py

@@ -6,7 +6,7 @@
 # Author: jianglin
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Email: xiyang0807@gmail.com
 # Created: 2016-12-15 20:46:13 (CST)
 # Created: 2016-12-15 20:46:13 (CST)
-# Last Update:星期三 2017-3-29 19:17:5 (CST)
+# Last Update:星期日 2017-4-2 15:5:23 (CST)
 #          By:
 #          By:
 # Description:
 # Description:
 # **************************************************************************
 # **************************************************************************
@@ -63,6 +63,14 @@ class Tags(db.Model, ModelMixin):
             tag_follower.c.tag_id == self.id,
             tag_follower.c.tag_id == self.id,
             tag_follower.c.follower_id == user.id).exists()
             tag_follower.c.follower_id == user.id).exists()
 
 
+    @property
+    def related_tags(self):
+        parent = self.parent
+        if not parent:
+            return []
+        relateds = parent.children.exclude_by(id=self.id).all()
+        return relateds
+
     def __str__(self):
     def __str__(self):
         return self.name
         return self.name
 
 

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

@@ -6,7 +6,7 @@
 # Author: jianglin
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Email: xiyang0807@gmail.com
 # Created: 2016-12-15 22:07:04 (CST)
 # Created: 2016-12-15 22:07:04 (CST)
-# Last Update:星期二 2017-3-28 17:25:34 (CST)
+# Last Update:星期日 2017-4-2 14:45:58 (CST)
 #          By:
 #          By:
 # Description:
 # Description:
 # **************************************************************************
 # **************************************************************************

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

@@ -6,7 +6,7 @@
 # Author: jianglin
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Email: xiyang0807@gmail.com
 # Created: 2016-12-15 22:07:39 (CST)
 # Created: 2016-12-15 22:07:39 (CST)
-# Last Update:星期日 2017-4-2 0:23:55 (CST)
+# Last Update:星期日 2017-4-2 14:49:1 (CST)
 #          By:
 #          By:
 # Description:
 # Description:
 # **************************************************************************
 # **************************************************************************
@@ -78,13 +78,17 @@ class TopicListView(MethodView):
         keys = ['title']
         keys = ['title']
         order_by = gen_order_by(query_dict, keys)
         order_by = gen_order_by(query_dict, keys)
         filter_dict = gen_filter_dict(query_dict, keys)
         filter_dict = gen_filter_dict(query_dict, keys)
+        title = _('All Topics')
         if request.path.endswith('good'):
         if request.path.endswith('good'):
             filter_dict.update(is_good=True)
             filter_dict.update(is_good=True)
+            title = _('Good Topics')
         elif request.path.endswith('top'):
         elif request.path.endswith('top'):
             filter_dict.update(is_top=True)
             filter_dict.update(is_top=True)
+            title = _('Top Topics')
         topics = Topic.query.filter_by(
         topics = Topic.query.filter_by(
             **filter_dict).order_by(*order_by).paginate(page, number, True)
             **filter_dict).order_by(*order_by).paginate(page, number, True)
-        return render_template('topic/topic_list.html', topics=topics)
+        data = {'title': title, 'topics': topics}
+        return render_template('topic/topic_list.html', **data)
 
 
     @form_validate(form_board, error=error_callback, f='')
     @form_validate(form_board, error=error_callback, f='')
     def post(self):
     def post(self):

+ 25 - 1
forums/count.py

@@ -6,7 +6,7 @@
 # Author: jianglin
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Email: xiyang0807@gmail.com
 # Created: 2017-03-29 21:28:52 (CST)
 # Created: 2017-03-29 21:28:52 (CST)
-# Last Update:星期日 2017-4-2 13:22:19 (CST)
+# Last Update:星期日 2017-4-2 15:24:37 (CST)
 #          By:
 #          By:
 # Description: 一些统计信息
 # Description: 一些统计信息
 # **************************************************************************
 # **************************************************************************
@@ -70,6 +70,8 @@ class Count(object):
             pipe = redis_data.pipeline()
             pipe = redis_data.pipeline()
             pipe.hincrby(key, 'topic', value)
             pipe.hincrby(key, 'topic', value)
             pipe.execute()
             pipe.execute()
+            cls.forums_post_count(1)
+            cls.forums_topic_count(1)
         return redis_data.hget(key, 'topic') or 0
         return redis_data.hget(key, 'topic') or 0
 
 
     @classmethod
     @classmethod
@@ -79,6 +81,7 @@ class Count(object):
             pipe = redis_data.pipeline()
             pipe = redis_data.pipeline()
             pipe.hincrby(key, 'replies', value)
             pipe.hincrby(key, 'replies', value)
             pipe.execute()
             pipe.execute()
+            cls.forums_post_count(1)
         return redis_data.hget(key, 'replies') or 0
         return redis_data.hget(key, 'replies') or 0
 
 
     @classmethod
     @classmethod
@@ -98,3 +101,24 @@ class Count(object):
         if value is not None:
         if value is not None:
             redis_data.hset(key, 'email', value)
             redis_data.hset(key, 'email', value)
         return redis_data.hget(key, 'email') or '2015-1-1 1:1:1'
         return redis_data.hget(key, 'email') or '2015-1-1 1:1:1'
+
+    @classmethod
+    def forums_user_count(cls, value=None):
+        key = 'count:forums'
+        if value is not None:
+            redis_data.hincrby(key, 'user', value)
+        return redis_data.hget(key, 'user') or 0
+
+    @classmethod
+    def forums_topic_count(cls, value=None):
+        key = 'count:forums'
+        if value is not None:
+            redis_data.hincrby(key, 'topic', value)
+        return redis_data.hget(key, 'topic') or 0
+
+    @classmethod
+    def forums_post_count(cls, value=None):
+        key = 'count:forums'
+        if value is not None:
+            redis_data.hincrby(key, 'post', value)
+        return redis_data.hget(key, 'post') or 0

+ 8 - 1
forums/filters.py

@@ -6,7 +6,7 @@
 # Author: jianglin
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Email: xiyang0807@gmail.com
 # Created: 2016-11-07 21:00:32 (CST)
 # Created: 2016-11-07 21:00:32 (CST)
-# Last Update:星期六 2017-4-1 20:16:51 (CST)
+# Last Update:星期日 2017-4-2 15:30:0 (CST)
 #          By:
 #          By:
 # Description:
 # Description:
 # **************************************************************************
 # **************************************************************************
@@ -81,6 +81,12 @@ def recent_tags():
     return tags
     return tags
 
 
 
 
+def forums_count():
+    from forums.extension import redis_data
+    key = 'count:forums'
+    return redis_data.hgetall(key)
+
+
 def is_not_confirmed(user):
 def is_not_confirmed(user):
     return (not user.is_confirmed and user.id == current_user.id)
     return (not user.is_confirmed and user.id == current_user.id)
 
 
@@ -91,6 +97,7 @@ def register_jinja2(app):
     app.jinja_env.globals['hot_tags'] = hot_tags
     app.jinja_env.globals['hot_tags'] = hot_tags
     app.jinja_env.globals['recent_tags'] = recent_tags
     app.jinja_env.globals['recent_tags'] = recent_tags
     app.jinja_env.globals['show_time'] = show_time
     app.jinja_env.globals['show_time'] = show_time
+    app.jinja_env.globals['forums_count'] = forums_count
     app.jinja_env.filters['timesince'] = timesince
     app.jinja_env.filters['timesince'] = timesince
     app.jinja_env.filters['safe_clean'] = safe_clean
     app.jinja_env.filters['safe_clean'] = safe_clean
     app.jinja_env.filters['is_not_confirmed'] = is_not_confirmed
     app.jinja_env.filters['is_not_confirmed'] = is_not_confirmed

BIN
forums/test.db


+ 1 - 1
requirements.txt

@@ -2,7 +2,7 @@ bleach==1.4.3
 cssmin==0.2.0
 cssmin==0.2.0
 Flask==0.11.1
 Flask==0.11.1
 Flask-Admin==1.4.2
 Flask-Admin==1.4.2
-Flask-Assets==0.11
+Flask-Assets==0.12
 Flask-Avatar==0.1.0
 Flask-Avatar==0.1.0
 Flask-BabelEx==0.9.3
 Flask-BabelEx==0.9.3
 Flask-Cache==0.13.1
 Flask-Cache==0.13.1

+ 2 - 2
templates/base/base.html

@@ -6,7 +6,7 @@
 {% from 'base/head.html' import breadcrumb %}
 {% from 'base/head.html' import breadcrumb %}
 
 
 {% block title -%}
 {% block title -%}
-  {{ title }} {{ SITE['title'] }} - {{ _(SITE['description']) }}
+  {{ title }} - {{ SITE['title'] }} - {{ _(SITE['description']) }}
 {%- endblock title %}
 {%- endblock title %}
 
 
 {% block script -%}
 {% block script -%}
@@ -15,7 +15,7 @@
 
 
 {% block style -%}
 {% block style -%}
   {{ super() }}
   {{ super() }}
-  <link href="http://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
+  <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
 {%- endblock style %}
 {%- endblock style %}
 
 
 {% block main %}
 {% block main %}

+ 1 - 1
templates/base/header.html

@@ -18,7 +18,7 @@
       <ul class="nav navbar-nav">
       <ul class="nav navbar-nav">
         {{ navlist(url_for('forums.forums'),_('Forums')) }}
         {{ navlist(url_for('forums.forums'),_('Forums')) }}
         {{ navlist(url_for('docs.list'),_('Wiki')) }}
         {{ navlist(url_for('docs.list'),_('Wiki')) }}
-        {{ navlist('#',_('Blog')) }}
+        {{ navlist('http://honmaple.org',_('Blog')) }}
         {{ navlist(url_for('topic.good'),_('Good')) }}
         {{ navlist(url_for('topic.good'),_('Good')) }}
       </ul>
       </ul>
       <form onsubmit="return dispatch()" class="navbar-form navbar-right" style="margin-top:10px;" >
       <form onsubmit="return dispatch()" class="navbar-form navbar-right" style="margin-top:10px;" >

+ 0 - 48
templates/base/notice.html

@@ -1,48 +0,0 @@
-{% import 'base/link.html' as link_base %}
-{% macro privacy(notice) -%}
-<small style="color:#999;">由{{ link_base.user(notice.send_user) }} 发来的私信:</small>
-<small class="pull-right">{{ notice.publish | timesince }}</small>
-<p style="margin-bottom:0px">{{ notice.content['content'] }}</p>
-{%- endmacro %}
-
-{% macro reply(notice) -%}
-{% set content = notice.content %}
-<small style="color:#999;"> {{ link_base.user(notice.send_user)}} 回复了你创建的主题:
-    <a href="{{ content['url'] }}">{{ content['title'] }}</a>
-</small>
-<small class="pull-right"> {{ notice.publish | timesince }} </small>
-<p style="margin-bottom:0px">{{ content["content"] | safe_clean }}</p>
-{%- endmacro %}
-
-{% macro rereply(notice) -%}
-{% set content = notice.content %}
-<small style="color:#999;">
-    {{ link_base.user(notice.send_user)}}在回复
-    <a href="{{ content['url'] }}">{{ content['title'] }}</a>时提到了你
-</small>
-<small class="pull-right"> {{ notice.publish | timesince }} </small>
-<p style="margin-bottom:0px">{{ content["content"] | safe_clean }}</p>
-{%- endmacro %}
-
-{% macro collect(notice) -%}
-{% set content = notice.content %}
-<small style="color:#999;"> {{ link_base.user(notice.send_user)}} 收藏了你创建的主题:
-    <a href="{{ content['url'] }}">{{ content['title'] }}</a>
-</small>
-<small class="pull-right"> {{ notice.publish | timesince }} </small>
-{%- endmacro %}
-
-{% macro like(notice) -%}
-{% set content = notice.content %}
-<small style="color:#999;"> {{ link_base.user(notice.send_user)}} 在
-    <a href="{{ content['url'] }}">{{ content['title'] }}</a> 赞了你回复
-</small>
-<small class="pull-right"> {{ notice.publish | timesince }} </small>
-<p style="margin-bottom:0px">{{ content["content"] | safe_clean }}</p>
-{%- endmacro %}
-
-{% macro user(notice) -%}
-{% set content = notice.content %}
-<small style="color:#999;"> {{ link_base.user(notice.send_user)}} 关注了你 </small>
-<small class="pull-right"> {{ notice.publish | timesince }} </small>
-{%- endmacro %}

+ 4 - 3
templates/base/panel.html

@@ -91,9 +91,10 @@
         {{ _('Forums Count') }}
         {{ _('Forums Count') }}
     </div>
     </div>
     <ul class="list-group">
     <ul class="list-group">
-        <li class="list-group-item">{{ _('Total number of registered users:')}} 0</li>
-        <li class="list-group-item">{{ _('Total number of topics:') }} 0 </li>
-        <li class="list-group-item">{{ _('Total number of posts:') }} 0 </li>
+        {% set count = forums_count() %}
+        <li class="list-group-item">{{ _('Total number of registered users:')}} {{ count['user'] }}</li>
+        <li class="list-group-item">{{ _('Total number of topics:') }} {{ count['topic'] }} </li>
+        <li class="list-group-item">{{ _('Total number of posts:') }} {{ count['post'] }} </li>
     </ul>
     </ul>
 </div>
 </div>
 {%- endmacro %}
 {%- endmacro %}

+ 0 - 2
templates/base/sort.html

@@ -1,2 +0,0 @@
-{% set topics = topics.items %}
-{% include 'topic/topic_list_base.html' %}

+ 1 - 1
templates/forums/index.html

@@ -9,7 +9,7 @@
 <div class="row hidden-sm hidden-xs">
 <div class="row hidden-sm hidden-xs">
     {{ forums_item(_('Forums'),url_for('forums.forums'),"fa-comments","#F86334")}}
     {{ forums_item(_('Forums'),url_for('forums.forums'),"fa-comments","#F86334")}}
     {{ forums_item(_('Wiki'),url_for('docs.list'),"fa-book","#eeccaa")}}
     {{ forums_item(_('Wiki'),url_for('docs.list'),"fa-book","#eeccaa")}}
-    {{ forums_item(_('Blog'),'https//honmaple.com',"fa-tasks")}}
+    {{ forums_item(_('Blog'),'http://honmaple.org',"fa-tasks")}}
     {{ forums_item(_('Good'),url_for('topic.good'),"fa-globe","#017e66")}}
     {{ forums_item(_('Good'),url_for('topic.good'),"fa-globe","#017e66")}}
 </div>
 </div>
 <div class="row">
 <div class="row">

+ 42 - 43
templates/tag/panel.html

@@ -1,60 +1,59 @@
 {% from 'base/panel.html' import base %}
 {% from 'base/panel.html' import base %}
 {% from 'base/panel.html' import count %}
 {% from 'base/panel.html' import count %}
 {% macro tag_list() -%}
 {% macro tag_list() -%}
-{{ base() }}
+  {{ base() }}
 {%- endmacro %}
 {%- endmacro %}
 
 
 {% macro tag(tag) -%}
 {% macro tag(tag) -%}
-{{ base() }}
-<div class="panel panel-default hidden-xs" style="font-size:13px;">
-  {{ parents(tag) }}
-  {{ children(tag) }}
-</div>
-{{ count() }}
+  {{ base() }}
+  <div class="panel panel-default hidden-xs" style="font-size:13px;">
+    {{ parents(tag) }}
+    {{ relation(tag) }}
+    {{ children(tag) }}
+  </div>
+  {{ count() }}
 {%- endmacro %}
 {%- endmacro %}
 
 
 {% macro parents(tag) -%}
 {% macro parents(tag) -%}
-<div class="panel-body" style="padding:10;margin:0;">
-  <strong>父节点</strong>
-</div>
-{% if tag.parents -%}
-{% for parent in tag.parents -%}
-{{ link(parent.name) }}
-{%- endfor %}
-<div style="border-bottom:1px solid #eee"></div>
-{{ relation(tag) }}
-{% else %}
-{{ link('honmaple') }}
-{%- endif %}
-<div style="border-bottom:1px solid #eee"></div>
+  <div class="panel-body" style="padding:10;margin:0;">
+    <strong>父节点</strong>
+  </div>
+  {% if tag.parent_id -%}
+    {{ link(tag.parent.name) }}
+  {% else %}
+    {{ link('honmaple') }}
+  {%- endif %}
+  <div style="border-bottom:1px solid #eee"></div>
 {%- endmacro %}
 {%- endmacro %}
 
 
-{% macro children(tag) -%}
-{% if tag.children -%}
-<div class="panel-body" style="padding:10;margin:0;">
-  <strong>子节点</strong>
-</div>
-{% for child in tag.children -%}
-{{ link(child.name) }}
-{%- endfor %}
-{%- endif %}
+{% macro relation(tag) -%}
+  {% set relates = tag.related_tags %}
+  {% if relates -%}
+    <div class="panel-body" style="padding:10;margin:0;">
+      <strong>相关节点</strong>
+    </div>
+    {% for child in relates -%}
+      {{ link(child.name) }}
+    {%- endfor %}
+  {%- endif %}
 {%- endmacro %}
 {%- endmacro %}
 
 
-{% macro relation(tag) -%}
-{% set parent = tag.parents[0] %}
-{% if parent.children -%}
-<div class="panel-body" style="padding:10;margin:0;">
-  <strong>相关节点</strong>
-</div>
-{% for child in parent.children if child.name != tag.name -%}
-{{ link(child.name) }}
-{%- endfor %}
-{%- endif %}
+{% macro children(tag) -%}
+  {% set children = tag.children.all() %}
+  {% if children -%}
+    <div class="panel-body" style="padding:10;margin:0;">
+      <strong>子节点</strong>
+    </div>
+    {% for child in children -%}
+      {{ link(child.name) }}
+    {%- endfor %}
+  {%- endif %}
 {%- endmacro %}
 {%- endmacro %}
 
 
+
 {% macro link(name) -%}
 {% macro link(name) -%}
-<div class="panel-body" style="padding:10px;margin-top:0;padding-top:0">
-  <img alt="" src="{{ url_for('avatar',text=name)}}" style="width:24px;"/>
-  <a class="text-capitalize" href="{{ url_for('tag.tag',name=name)}}" style="color:#555;">{{ name }}</a>
-</div>
+  <div class="panel-body" style="padding:10px;margin-top:0;padding-top:0">
+    <img alt="" src="{{ url_for('avatar',text=name)}}" style="width:24px;"/>
+    <a class="text-capitalize" href="{{ url_for('tag.tag',name=name)}}" style="color:#555;">{{ name }}</a>
+  </div>
 {%- endmacro %}
 {%- endmacro %}

+ 1 - 1
templates/tag/tag_list.html

@@ -9,7 +9,7 @@
         </div>
         </div>
         <div class="panel-body">
         <div class="panel-body">
           {% for tag in tags.items %}
           {% for tag in tags.items %}
-            <a class="tag" href="{{ url_for('tag.tag',name=tag.name)}}">{{ tag.name }}</a>
+            <a class="tag" href="{{ url_for('tag.tag',name=tag.name) }}">{{ tag.name }}</a>
           {% else %}
           {% else %}
             <span class="text-center">
             <span class="text-center">
               {{ _('No Tags') }}
               {{ _('No Tags') }}

+ 16 - 10
templates/topic/topic_list.html

@@ -1,15 +1,21 @@
 {% extends 'base/base.html' %}
 {% extends 'base/base.html' %}
 {% block content %}
 {% block content %}
-{{ breadcrumb(active=_('All Topics')) }}
-<div class="row">
-  <div class="col-md-9">
-    <div class="panel panel-default">
-      {% include "topic/_topic.html" %}
-      {{ p_footer(topics,'topic.list')}}
+  {% if request.path.endswith('top') %}
+    {{ breadcrumb(hrefs={_('All Topics'):url_for('topic.list')},active=_('Top Topics')) }}
+  {% elif request.path.endswith('good') %}
+    {{ breadcrumb(hrefs={_('All Topics'):url_for('topic.list')},active=_('Good Topics')) }}
+  {% else %}
+    {{ breadcrumb(active=_('All Topics')) }}
+  {% endif %}
+  <div class="row">
+    <div class="col-md-9">
+      <div class="panel panel-default">
+        {% include "topic/_topic.html" %}
+        {{ p_footer(topics,'topic.list')}}
+      </div>
+    </div>
+    <div class="col-md-3" style="padding-left:0">
+      {{ panel_base.topic_list() }}
     </div>
     </div>
   </div>
   </div>
-  <div class="col-md-3" style="padding-left:0">
-    {{ panel_base.topic_list() }}
-  </div>
-</div>
 {% endblock %}
 {% endblock %}

+ 10 - 2
upgrade_count.py

@@ -6,15 +6,22 @@
 # Author: jianglin
 # Author: jianglin
 # Email: xiyang0807@gmail.com
 # Email: xiyang0807@gmail.com
 # Created: 2017-04-02 13:00:02 (CST)
 # Created: 2017-04-02 13:00:02 (CST)
-# Last Update:星期日 2017-4-2 13:47:2 (CST)
+# Last Update:星期日 2017-4-2 15:52:41 (CST)
 #          By:
 #          By:
 # Description:
 # Description:
 # **************************************************************************
 # **************************************************************************
-from runserver import app
 from forums.api.topic.models import Topic, Reply
 from forums.api.topic.models import Topic, Reply
 from forums.api.forums.models import Board
 from forums.api.forums.models import Board
 from forums.api.user.models import User
 from forums.api.user.models import User
 from forums.extension import redis_data
 from forums.extension import redis_data
+from runserver import app
+
+
+def forums():
+    key = 'count:forums'
+    redis_data.hset(key, 'user', User.query.count())
+    redis_data.hset(key, 'topic', Topic.query.count())
+    redis_data.hset(key, 'post', Reply.query.count() + Topic.query.count())
 
 
 
 
 def topic():
 def topic():
@@ -75,6 +82,7 @@ def board():
 
 
 def main():
 def main():
     with app.app_context():
     with app.app_context():
+        forums()
         topic()
         topic()
         board()
         board()
         user()
         user()