Merge branch 'collection' of csgitlab.ucd.ie:19206226/q-a_platform into collection

 Conflicts:
	data-dev.sqlite
merge-requests/3/head
Yang Liuxin 3 years ago
commit c7c3df1dca

@ -0,0 +1 @@
FLASK_APP=flasky.py

2
.gitignore vendored

@ -105,7 +105,6 @@ celerybeat.pid
*.sage.py
# Environments
.env
.venv
env/
venv/
@ -140,4 +139,5 @@ cython_debug/
.idea
#data-dev.sqlite

@ -6,11 +6,13 @@ from flask import render_template, redirect, url_for, flash, request, \
from flask_login import login_required, current_user
from sqlalchemy.sql.functions import func
from werkzeug.utils import secure_filename
from . import main
from .forms import UploadPhotoForm, CommentForm, PostMdForm
from .. import db, csrf
from ..models import Permission, User, Post, Comment, Notification, Like, Transaction, Activity, Collect, Want, Question
from ..decorators import permission_required
from ..util import check_text
@main.route('/', methods=['GET', 'POST'])
@ -282,14 +284,15 @@ def user(username):
wanting = user.wanted_Activity
posts = user.posts.order_by(Post.timestamp.desc())
questions=user.questions.order_by(Question.timestamp.desc())
questions = user.questions.order_by(Question.timestamp.desc())
liking_posts = [{'post': item.liked_post, 'timestamp': item.timestamp} for item in
liking.order_by(Like.timestamp.desc())]
transactions = user.transactions.order_by(Transaction.timestamp.desc())
activities = user.activities.order_by(Activity.timestamp.desc())
collects = collecting.order_by(Collect.timestamp.desc())
wants = wanting.order_by(Want.timestamp.desc())
return render_template('user.html', user=user, posts=posts, questions=questions,liking_posts=liking_posts, activities=activities,
return render_template('user.html', user=user, posts=posts, questions=questions, liking_posts=liking_posts,
activities=activities,
transactionsInProfile=transactions, collects=collects, wants=wants, )
@ -458,6 +461,27 @@ def delete_post_inProfile(post_id):
return redirect(url_for('.user', username=current_user.username))
@main.route('/send_message/<username>/<message>')
@login_required
def send_message(username, message):
currentUserObj: User = current_user
user: User = User.query.filter_by(username=username).first()
if user is None:
flash('Invalid user.')
return redirect(url_for('.index'))
check = check_text(message)
print(check)
if check["conclusionType"] != 1:
data = check['data'][0]["msg"]
flash('Your message violated the rule of our web site. '+ message + " " + data)
return redirect(url_for('.user', username=username))
currentUserObj.send_message(user, message)
db.session.commit()
flash('You have sent:' + message + " To: " + username)
return redirect(url_for('.user', username=username))
@main.route('/follow/<username>')
@login_required
@permission_required(Permission.FOLLOW)
@ -516,24 +540,21 @@ def like(post_id):
@csrf.exempt
@permission_required(Permission.FOLLOW)
def AJAXlike(post_id):
if(current_user is None):
if (current_user is None):
return redirect(url_for("/"))
post = Post.query.filter_by(id=post_id).first()
if post is not None:
if(current_user.is_liking(post)):
if (current_user.is_liking(post)):
current_user.dislike(post)
post.dislike(current_user)
db.session.commit()
return jsonify({'code': 200, 'like': False, 'num':post.liker.count()})
return jsonify({'code': 200, 'like': False, 'num': post.liker.count()})
else:
current_user.like(post)
post.like(current_user)
post.recent_activity = datetime.utcnow()
db.session.commit()
return jsonify({'code': 200, 'like': True, 'num':post.liker.count()})
return jsonify({'code': 200, 'like': True, 'num': post.liker.count()})
@main.route('/likeinpost/<post_id>')
@ -692,10 +713,10 @@ def new_question_md():
return render_template('new_posting/new_mdpost.html', form=form)
body_html = request.form['test-editormd-html-code']
question = Question(title=title,
body=body,
body_html=body_html,
is_anonymous=is_anonymous,
author=current_user._get_current_object())
body=body,
body_html=body_html,
is_anonymous=is_anonymous,
author=current_user._get_current_object())
question.recent_activity = datetime.utcnow()
db.session.add(question)
db.session.commit()
@ -735,9 +756,10 @@ def new_answer_md(question_id):
flash("You have just posted a posting anonymously", 'success')
else:
flash("You have just posted a posting", 'success')
return redirect(url_for('.view_question',question_id=question_id))
return redirect(url_for('.view_question', question_id=question_id))
return render_template('new_posting/new_mdanswer.html', form=form)
@main.route('/questions/<question_id>', methods=['GET', 'POST'])
def view_question(question_id):
if request.method == 'GET':
@ -762,7 +784,8 @@ def view_question(question_id):
item.important = li_num
hot_activity = li.order_by(Activity.important.desc())
return render_template('Posts/question.html', posts1=posts1, posts5=hot,
pagination1=pagination1, hot_activity=hot_activity, question=question,question_id=question_id)
pagination1=pagination1, hot_activity=hot_activity, question=question,
question_id=question_id)
else:
inf = request.form["search"]
return redirect(url_for('.query', content=inf))

@ -79,6 +79,20 @@ class Students(db.Model):
role_id = db.Column(db.Integer, default=1, index=True)
class Savequestion(db.Model):
__tablename__ = 'savequestion'
saver_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)
question_id = db.Column(db.Integer, db.ForeignKey('questions.id'), primary_key=True)
timestamp = db.Column(db.DateTime, default=datetime.utcnow)
class Saveanswer(db.Model):
__tablename__ = 'saveanswer'
saver_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)
answer_id = db.Column(db.Integer, db.ForeignKey('posts.id'), primary_key=True)
timestamp = db.Column(db.DateTime, default=datetime.utcnow)
class Follow(db.Model):
follower_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)
followed_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)
@ -140,6 +154,12 @@ class User(UserMixin, db.Model):
# collect
collected_transaction = db.relationship('Collect', back_populates='collecter',
lazy='dynamic', cascade='all, delete-orphan')
# # # # save
saved_questions = db.relationship('Savequestion', foreign_keys=[Savequestion.saver_id], backref=db.backref('saver', lazy='joined'),
lazy='dynamic', cascade='all, delete-orphan')
aved_answers = db.relationship('Saveanswer', foreign_keys=[Saveanswer.saver_id],
backref=db.backref('saver', lazy='joined'),
lazy='dynamic', cascade='all, delete-orphan')
@staticmethod
def add_self_follows():
@ -255,6 +275,13 @@ class User(UserMixin, db.Model):
return '{url}/{hash}?s={size}&d={default}&r={rating}'.format(
url=url, hash=hash, size=size, default=default, rating=rating)
def send_message(self, user, message):
n = Notification(receiver_id=user.id, timestamp=datetime.utcnow(),
username=self.username, action=" has sent you a message: " + message + " ",
object="you")
db.session.add(n)
db.session.commit()
def follow(self, user):
if not self.is_following(user):
f = Follow(follower=self, followed=user)
@ -333,6 +360,31 @@ class User(UserMixin, db.Model):
return self.followers.filter_by(
follower_id=user.id).first() is not None
def is_savingquestion(self, question):
return self.saved_questions.filter_by(question_id=question.id).first() is not None
def savequestion(self, question):
if not self.is_savingquestion(question):
s = Savequestion(saver=self, question=question)
db.session.add(s)
def unsavequestion(self, question):
s = self.saved_questions.filter_by(question_id=question.id).first()
db.session.delete(s)
def is_savinganswer(self, answer):
return self.saved_answers.filter_by(answer_id=answer.id).first() is not None
def saveanswer(self, answer):
if not self.is_savinganswer(answer):
s = Saveanswer(saver=self, answer=answer)
db.session.add(s)
def unsaveanswer(self, answer):
s = self.saved_answers.filter_by(answer_id=answer.id).first()
db.session.delete(s)
@property
def followed_posts(self):
return Post.query.join(Follow, Follow.followed_id == Post.author_id) \
@ -386,6 +438,8 @@ def load_user(user_id):
return User.query.get(int(user_id))
class Question(db.Model):
__tablename__ = 'questions'
id = db.Column(db.Integer, primary_key=True)
@ -398,6 +452,10 @@ class Question(db.Model):
recent_activity = db.Column(db.DateTime, index=True, default=datetime.utcnow())
answers = db.relationship('Post', back_populates='question', cascade='all, delete-orphan', lazy='dynamic')
is_anonymous = db.Column(db.Boolean, default=False)
savers = db.relationship('Savequestion', foreign_keys=[Savequestion.question_id],
backref=db.backref('question', lazy='joined'), lazy='dynamic',
cascade='all, delete-orphan')
class Post(db.Model):
__tablename__ = 'posts'
@ -414,6 +472,10 @@ class Post(db.Model):
question_id = db.Column(db.Integer, db.ForeignKey('questions.id'))
liker = db.relationship('Like', back_populates='liked_post', lazy='dynamic', cascade='all')
is_anonymous = db.Column(db.Boolean, default=False)
savers = db.relationship('Saveanswer', foreign_keys=[Saveanswer.answer_id],
backref=db.backref('answer', lazy='joined'), lazy='dynamic',
cascade='all, delete-orphan')
# saver = db.relationship('Save_post', back_populates='saved_post', lazy='dynamic', cascade='all')
def like(self, user):
if not self.is_liked_by(user):
@ -477,6 +539,14 @@ class Like(db.Model):
liker = db.relationship('User', back_populates='liked_post', lazy='joined')
liked_post = db.relationship('Post', back_populates='liker', lazy='joined')
# class Save_post(db.Model):
# __tablename__ = 'save_posts'
# save_post_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)
# save_post_id = db.Column(db.Integer, db.ForeignKey('posts.id'), primary_key=True)
# timestamp = db.Column(db.DateTime, default=datetime.utcnow)
# saver = db.relationship('User', back_populates='saved_poster', lazy='joined')
# saved_post = db.relationship('Post', back_populates='saver', lazy='joined')
# #
class Collect(db.Model):
@ -579,3 +649,6 @@ class Activity(db.Model):
return False
return self.wanter.filter_by(
wanter_id=user.id).first() is not None

@ -15,8 +15,8 @@ body {
/*box-shadow: 0 0 10px 2px #e3e3e3;*/
}
.panel {
margin-top: 5px;
margin-bottom: 5px;
margin-top: 16px;
margin-bottom: 16px;
}
/*

@ -0,0 +1,133 @@
<li class="post" id="{{ post.id }}">
<div class="panel panel-default">
<div class="panel-body">
<div class="post-content col-sm-12">
{# 标题#}
{# <h3 class="post-title" style="margin-top: 7px">#}
{# <a href="{{ url_for('.post', id=post.id) }}">#}
{# {{ post.title }}#}
{# </a>#}
{# </h3>#}
{# 摘要#}
<div class="post-body">
<p>
{% if post.body_html %}
{{ post.body_html |safe|striptags|truncate(260,killwords=Flase,leeway=0) }}
{% else %}
{{ post.body |truncate(200,killwords=Flase,leeway=0)}}
{% endif %}
<small><a href="{{ url_for('.post', id=post.id) }}"><B>Read More</B></a></small></p>
</div>
</div>
</div>
<div class="panel-footer">
{% if post.is_anonymous %}
<div class="post-thumbnail">
<span class="head-photo">
<img class="img-rounded profile-thumbnail" src="{{ url_for('static',filename='Image/anonymous.png') }}" alt="avatar" style="width: 25px; height: 25px">
</span>
<span class="post-author">
<span> anonymous </span>
</span>
<span class="post-date"><small>{{ moment(post.timestamp).fromNow() }}</small></span>
</div>
{% else %}
<div class="post-thumbnail">
<a class="head-photo" href="{{ url_for('.user', username=post.author.username) }}">
{% if post.author.avatar_img %}
<img class="img-rounded profile-thumbnail" src="{{ post.author.avatar_img }}" alt="avatar" style="width: 25px; height: 25px">
{% else %}
<img class="img-rounded profile-thumbnail" src="{{ post.author.gravatar(size=25) }}" alt="avatar">
{% endif %}
</a>
<span class="post-author">
<a href="{{ url_for('.user', username=post.author.username) }}">
{{ post.author.username }}
{% if post.author.can(Permission.ACTIVITY) %}
<svg class="icon" viewBox="0 0 1024 1024" width="14" height="14" style="margin: 0">
<path d="M959.786667 148.906667l-44.330667-0.725333c-1.024 0-100.437333-2.048-203.050667-41.728-105.301333-40.789333-173.141333-87.552-173.781333-88.021333L511.872 0 485.248 18.474667C484.608 18.901333 416.768 65.706667 311.466667 106.453333 208.938667 146.218667 109.482667 148.181333 108.544 148.181333L64 148.906667l0 430.464C64 795.477333 355.328 1024 511.957333 1024 668.714667 1024 960 795.477333 960 579.370667L959.786667 148.906667zM321.877333 772.48 321.877333 355.413333 282.112 355.413333 282.112 317.482667 441.173333 317.482667l0 189.610667 200.192-189.610667 157.696 0L321.877333 772.48z" fill="#3688FF"></path>
</svg>
{% endif %}
</a>
</span>
<span class="post-date"><small>{{ moment(post.timestamp).fromNow() }}</small></span>
</div>
{% endif %}
<div class="post-footer">
{# 评论#}
<a class="icon-btn" style="float:right" href="{{ url_for('.post', id=post.id) }}#comments">
<span class="glyphicon glyphicon-comment"></span>
<span>{{ post.comments.count() }} comment</span>
</a>
{# 喜欢#}
{# {% if not current_user.is_liking(post) %}#}
{# <a class="icon-btn" style="float:right; margin-right: 15px" href="{{ url_for('.like', post_id=post.id) }}#{{ post.id }}">#}
{# <span class="glyphicon glyphicon-heart-empty"></span>#}
{# <span>{{ post.liker.count() }} likes</span>#}
{# </a>#}
<a class="icon-btn" style="float:right; margin-right: 15px" href="javascript:void (0);" onclick="{
var csrftoken = $('meta[name=csrf-token]').attr('content');
var _this=this;
var span1=this.childNodes[1];
var span2=this.childNodes[3];
{#console.log(this.childNodes[3]);#}
{#console.log(this.childElementCount);#}
var sendData={
'csrf_token':csrftoken
};
$.ajax({
url: '{{ url_for('.AJAXlike', post_id=post.id) }}',
type: 'POST',
{#dataType: 'json',#}
{#contentType: 'application/json',#}
{#data: JSON.stringify(sendData),#}
success: function(result) {
console.log('success\n'+result);
if(result.like){
span1.setAttribute('class', 'glyphicon glyphicon-heart');
}else{
span1.setAttribute('class', 'glyphicon glyphicon-heart-empty');
}
span2.innerText=result.num+' likes';
{#span1.setAttribute('href', '{{ url_for('.dislike', post_id=post.id) }}');#}
},
error:function(msg){
console.log(msg);
if(msg.status===403){
window.location.href='{{ url_for('auth.login') }}'
}
}
})
}">
{% if not current_user.is_liking(post) %}
<span class="glyphicon glyphicon-heart-empty"></span>
{% else %}
<span class="glyphicon glyphicon-heart"></span>
{% endif %}
<span>{{ post.liker.count() }} likes</span>
</a>
{# {% else %}#}
{# <a class="icon-btn" style="float:right; margin-right: 15px" href="{{ url_for('.dislike', post_id=post.id) }}#{{ post.id }}">#}
{# <span class="glyphicon glyphicon-heart"></span>#}
{# <span>{{ post.liker.count() }} likes</span>#}
{# </a>#}
{# {% endif %}#}
</div>
</div>
</div>
</li>

@ -0,0 +1,46 @@
<ul class="posts list-unstyled">
{% for post in concernAnswers %}
{% if post.is_anonymous==False %}
<li class="post">
<div class="post-box">
<div class="post-content">
<h3 class="post-title">
<a href="{{ url_for('.post', id=post.id) }}">{{ post.title }}</a>
</h3>
<div class="post-body">
<p>
{% if post.body_html %}
{{ post.body_html |safe|striptags|truncate(260,killwords=Flase,leeway=0) }}
{% else %}
{{ post.body |truncate(200,killwords=Flase,leeway=0)}}
{% endif %}
<small><a href="{{ url_for('.post', id=post.id) }}"><B>Read More</B></a></small>
</p>
</div>
<div class="post-footer">
<span class="post-date">
<span class="glyphicon glyphicon-time"></span>
{{ moment(post.timestamp).fromNow() }}
</span>
{% if current_user == post.author %}
{# 删除#}
<a class="icon-btn" href="{{ url_for('main.delete_post_inProfile', post_id=post.id)}}">
<span class="glyphicon glyphicon-trash"></span>
<span>delete</span>
</a>
{# 修改 #}
<a class="icon-btn" href="#">
<span class="glyphicon glyphicon-pencil"></span>
<span>modification</span>
</a>
{% endif %}
</div>
</div>
</div>
</li>
{% endif %}
{% endfor %}
</ul>

@ -0,0 +1,46 @@
<ul class="posts list-unstyled">
{% for post in concernQuestions %}
{% if post.is_anonymous==False %}
<li class="post">
<div class="post-box">
<div class="post-content">
<h3 class="post-title">
<a href="{{ url_for('.post', id=post.id) }}">{{ post.title }}</a>
</h3>
<div class="post-body">
<p>
{% if post.body_html %}
{{ post.body_html |safe|striptags|truncate(260,killwords=Flase,leeway=0) }}
{% else %}
{{ post.body |truncate(200,killwords=Flase,leeway=0)}}
{% endif %}
<small><a href="{{ url_for('.post', id=post.id) }}"><B>Read More</B></a></small>
</p>
</div>
<div class="post-footer">
<span class="post-date">
<span class="glyphicon glyphicon-time"></span>
{{ moment(post.timestamp).fromNow() }}
</span>
{% if current_user == post.author %}
{# 删除#}
<a class="icon-btn" href="{{ url_for('main.delete_post_inProfile', post_id=post.id)}}">
<span class="glyphicon glyphicon-trash"></span>
<span>delete</span>
</a>
{# 修改 #}
<a class="icon-btn" href="#">
<span class="glyphicon glyphicon-pencil"></span>
<span>modification</span>
</a>
{% endif %}
</div>
</div>
</div>
</li>
{% endif %}
{% endfor %}
</ul>

@ -125,7 +125,7 @@
<div class="tabbable">
<ul class="nav post-nav">
<li id="btn-1">
<a href="#" class="glyphicon glyphicon-bookmark"> Follow</a>
<a href="{{ url_for('.save_question', question_id=question.id ) }}" class="glyphicon glyphicon-bookmark"> Follow</a>
</li>
<li id="btn-2">
<a href="{{ url_for('.new_answer_md',question_id=question_id )}}" class="glyphicon glyphicon-pencil">
@ -169,7 +169,7 @@
<div class="tab-pane active" id="panel-1">
<ul class="posts list-unstyled">
{% for post in posts1 %}
{% include 'Posts/_posts.html' %}
{% include 'Posts/_answers.html' %}
{% endfor %}
</ul>
{% if pagination1 %}

@ -61,7 +61,7 @@
<input name="confirm_pwd" id="confirm_pwd" type="password" class="form-control" placeholder="Confirm password">
<p id="pwd"></p>
<button class="btn btn-lg btn-warning btn-block chose" disabled="disabled" id="submit" type="submit">Submit</button>
<button class="btn btn-lg btn-warning btn-block chose" disabled="disabled" id="submit1" type="submit">Submit</button>
</form>
</div>
<div class="form-container sign-in-container">
@ -80,16 +80,16 @@
<p id="p2" class="text-danger"></p>
<div>
{# <label>完成验证:</label>#}
<label>完成验证:</label>
<div id="captcha">
{# <p id="wait" class="show"></p>#}
<p id="wait" class="show"></p>
</div>
</div>
<br>
<p id="notice" class="hide">请先完成验证</p>
<button class="btn btn-lg btn-warning btn-block chose" id="submit" disabled="disabled"
<button class="btn btn-lg btn-warning btn-block chose" id="submit0" disabled="disabled"
type="submit">Sign in
</button>
@ -125,23 +125,23 @@
var info = document.getElementById('p1');
var pwd = document.getElementById('inputPassword');
//学号
{#stuID.onblur = function () {#}
{# var stuid = this.value;#}
{# var reg = /[0-9]{1,4}/;#}
stuID.onblur = function () {
var stuid = this.value;
var reg = /[0-9]{1,4}/;
{#var reg = /^\d{18}$/;#}
{# // 不符合规则的话#}
{# if (!reg.test(stuid)) {#}
{# info.innerHTML = 'Please enter StudentID or OrganizationID';#}
{# info.className = 'text-danger';#}
{# document.getElementById("submit").disabled = true;#}
{# } else {#}
{# info.innerHTML = '';#}
{# info.className = 'text-success';#}
{# }#}
{# if (info.className == 'text-success') {#}
{# document.getElementById("submit").disabled = false;#}
{# }#}
{#}#}
// 不符合规则的话
if (!reg.test(stuid)) {
info.innerHTML = 'Please enter StudentID or OrganizationID';
info.className = 'text-danger';
document.getElementById("submit0").disabled = true;
} else {
info.innerHTML = '';
info.className = 'text-success';
}
if (info.className == 'text-success') {
document.getElementById("submit0").disabled = false;
}
}
var handler = function (captchaObj) {
$("#submit").click(function (e) {
var result = captchaObj.getValidate();

@ -5,7 +5,7 @@
{% block title %}Profile{% endblock %}
{% block head %}
{{ super() }}
{{ super() }}
<!-- Custom styles for this template -->
<link href="{{ url_for('static',filename='profile.css') }}" rel="stylesheet">
@ -13,125 +13,144 @@
{% block page_content %}
<div class="container">
<div class="bg-profile" style="height: 280px">
</div>
<div class="container col-sm-12 info">
<div class="col-md-2" style="padding: 0; margin: 20px 20px 20px 110px">
<div class="photo">
{% if user.avatar_img %}
<img class="img-rounded profile-thumbnail" src="{{ user.avatar_img }}" alt="avatar" style="width: 130px; height: 130px">
{% else %}
<img class="img-rounded profile-thumbnail" src="{{ user.gravatar(size=130) }}" alt="avatar">
{% endif %}
</div>
<div>
<div class="detail">
<span class="glyphicon glyphicon-calendar" aria-hidden="true"></span>
<span>Joined {{ moment(user.member_since).format('L') }}</span>
</div>
<div class="detail">
<span class="glyphicon glyphicon-edit" aria-hidden="true"></span>
<span>Last seen {{ moment(user.last_seen).fromNow() }}</span>
<div class="container">
<div class="bg-profile" style="height: 280px">
</div>
<div class="container col-sm-12 info">
<div class="col-md-2" style="padding: 0; margin: 20px 20px 20px 110px">
<div class="photo">
{% if user.avatar_img %}
<img class="img-rounded profile-thumbnail" src="{{ user.avatar_img }}" alt="avatar"
style="width: 130px; height: 130px">
{% else %}
<img class="img-rounded profile-thumbnail" src="{{ user.gravatar(size=130) }}" alt="avatar">
{% endif %}
</div>
<div>
<div class="detail">
<span class="glyphicon glyphicon-calendar" aria-hidden="true"></span>
<span>Joined {{ moment(user.member_since).format('L') }}</span>
</div>
<div class="detail">
<span class="glyphicon glyphicon-edit" aria-hidden="true"></span>
<span>Last seen {{ moment(user.last_seen).fromNow() }}</span>
</div>
<div class="follow">
<a href="{{ url_for('.followers', username=user.username) }}">Followers: <span class="badge">{{ user.followers.count() - 1 }}</span></a>&nbsp;
<a href="{{ url_for('.followed_by', username=user.username) }}">Following: <span class="badge">{{ user.following.count() - 1 }}</span></a>
<div class="follow">
<a href="{{ url_for('.followers', username=user.username) }}">Followers: <span
class="badge">{{ user.followers.count() - 1 }}</span></a>&nbsp;
<a href="{{ url_for('.followed_by', username=user.username) }}">Following: <span
class="badge">{{ user.following.count() - 1 }}</span></a>
</div>
</div>
</div>
</div>
<div class="col-sm-offset-2 col-md-6" style="margin-top: 35px;margin-left: 80px;">
<ul class="list-group">
<li class="list-group-item info-box">
<h3 style="display: inline;">{{ user.username }}
{% if user.can(Permission.ACTIVITY) %}
<svg class="icon" viewBox="0 0 1024 1024" width="22" height="22">
<path d="M959.786667 148.906667l-44.330667-0.725333c-1.024 0-100.437333-2.048-203.050667-41.728-105.301333-40.789333-173.141333-87.552-173.781333-88.021333L511.872 0 485.248 18.474667C484.608 18.901333 416.768 65.706667 311.466667 106.453333 208.938667 146.218667 109.482667 148.181333 108.544 148.181333L64 148.906667l0 430.464C64 795.477333 355.328 1024 511.957333 1024 668.714667 1024 960 795.477333 960 579.370667L959.786667 148.906667zM321.877333 772.48 321.877333 355.413333 282.112 355.413333 282.112 317.482667 441.173333 317.482667l0 189.610667 200.192-189.610667 157.696 0L321.877333 772.48z" fill="#3688FF"></path>
</svg>
{% endif %}
</h3>
{% if current_user.can(Permission.FOLLOW) and user != current_user %}
<div class="col-sm-offset-2 col-md-6" style="margin-top: 35px;margin-left: 80px;">
<ul class="list-group">
<li class="list-group-item info-box">
<h3 style="display: inline;">{{ user.username }}
{% if user.can(Permission.ACTIVITY) %}
<svg class="icon" viewBox="0 0 1024 1024" width="22" height="22">
<path d="M959.786667 148.906667l-44.330667-0.725333c-1.024 0-100.437333-2.048-203.050667-41.728-105.301333-40.789333-173.141333-87.552-173.781333-88.021333L511.872 0 485.248 18.474667C484.608 18.901333 416.768 65.706667 311.466667 106.453333 208.938667 146.218667 109.482667 148.181333 108.544 148.181333L64 148.906667l0 430.464C64 795.477333 355.328 1024 511.957333 1024 668.714667 1024 960 795.477333 960 579.370667L959.786667 148.906667zM321.877333 772.48 321.877333 355.413333 282.112 355.413333 282.112 317.482667 441.173333 317.482667l0 189.610667 200.192-189.610667 157.696 0L321.877333 772.48z"
fill="#3688FF"></path>
</svg>
{% endif %}
</h3>
{% if current_user.can(Permission.FOLLOW) and user != current_user %}
{% if not current_user.is_following(user) %}
<a href="{{ url_for('.follow', username=user.username) }}" class="btn btn-follow">Follow</a>
<a href="{{ url_for('.follow', username=user.username) }}"
class="btn btn-follow">Follow</a>
{% else %}
<a href="{{ url_for('.unfollow', username=user.username) }}" class="btn btn-unfollow" id="unfollow">Followed</a>
<a href="{{ url_for('.unfollow', username=user.username) }}" class="btn btn-unfollow"
id="unfollow">Followed</a>
{% endif %}
{% endif %}
</li>
<li class="list-group-item info-box" style="color: #727070;">
{{ user.about_me }}
</li>
<li class="list-group-item info-box detail">
<div class="col-sm-2 title">Email</div>
<div class="col-sm-10">{{ user.email }}</div>
</li>
<li class="list-group-item info-box detail">
<div class="col-sm-2 title">Grade</div>
<div class="col-sm-10">{{ user.grade }}</div>
</li>
<li class="list-group-item info-box detail">
<div class="col-sm-2 title">Collage</div>
<div class="col-sm-10">{{ user.college }}</div>
</li>
</ul>
</div>
{% if user == current_user %}
<div class="btn-group btn-group-sm set-info" >
<button type="button" class="btn btn-default" href="/edit-profile">
<a href="/edit-profile">Change my information</a>
</button>
{% endif %}
</li>
<li class="list-group-item info-box" style="color: #727070;">
{{ user.about_me }}
</li>
<li class="list-group-item info-box detail">
<div class="col-sm-2 title">Email</div>
<div class="col-sm-10">{{ user.email }}</div>
</li>
<li class="list-group-item info-box detail">
<div class="col-sm-2 title">Grade</div>
<div class="col-sm-10">{{ user.grade }}</div>
</li>
<li class="list-group-item info-box detail">
<div class="col-sm-2 title">Collage</div>
<div class="col-sm-10">{{ user.college }}</div>
</li>
<li class="list-group-item info-box detail">
<div class="input-private-message-box">
<input id="input-text-value" class="col-sm-10" type="text">
</div>
</li>
<li class="list-group-item info-box detail">
<div class="input-private-message-box">
<button class="col-sm-10" value="Send" onclick="send_message()">Send</button>
</div>
</li>
</ul>
</div>
{% endif %}
</div>
<div class="container col-sm-12 info">
<div class="tabbable">
<ul class="nav post-nav">
<li class="active" id="btn-1">
<a href="#panel-1" data-toggle="tab">My answers</a>
</li>
{% if user == current_user %}
<div class="btn-group btn-group-sm set-info">
<button type="button" class="btn btn-default" href="/edit-profile">
<a href="/edit-profile">Change my information</a>
</button>
</div>
{% endif %}
</div>
<div class="container col-sm-12 info">
<div class="tabbable">
<ul class="nav post-nav">
<li class="active" id="btn-1">
<a href="#panel-1" data-toggle="tab">My answers</a>
</li>
<li id="btn-7">
<a href="#panel-7" data-toggle="tab">My questions</a>
</li>
<li id="btn-2">
<a href="#panel-2" data-toggle="tab">Likes</a>
</li>
<a href="#panel-7" data-toggle="tab">My questions</a>
</li>
<li id="btn-2">
<a href="#panel-2" data-toggle="tab">Likes</a>
</li>
{% if user.can(Permission.ACTIVITY) %}
<li id="btn-4">
<a href="#panel-4" data-toggle="tab">MyAnnouncements</a>
</li>
</li>
{% else %}
<li id="btn-3">
<a href="#panel-3" data-toggle="tab">MyTransactions</a>
</li>
<li id="btn-6">
<a href="#panel-6" data-toggle="tab">ShoppingCart</a>
<a href="#panel-6" data-toggle="tab">ShoppingCart</a>
</li>
{% endif %}
<li id="btn-5">
<a href="#panel-5" data-toggle="tab">WantToGo</a>
</li>
</ul>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="panel-1">
<div class="tab-content">
<div class="tab-pane active" id="panel-1">
<ul class="posts list-unstyled">
{% include 'Posts/_postsInProfile.html' %}
{% include 'Posts/_postsInProfile.html' %}
</ul>
</div>
</div>
<div class="tab-pane active" id="panel-7">
<ul class="posts list-unstyled">
{% include 'Posts/_answersInProfile.html' %}
{% include 'Posts/_answersInProfile.html' %}
</ul>
</div>
<div class="tab-pane" id="panel-2">
</div>
<div class="tab-pane" id="panel-2">
<ul class="like_posts list-unstyled">
{% include 'Posts/_postsLikingInProfile.html' %}
{% include 'Posts/_postsLikingInProfile.html' %}
</ul>
</div>
</div>
{% if user.can(Permission.ACTIVITY) %}
<div class="tab-pane" id="panel-4">
<ul class="_activity list-unstyled">
@ -159,165 +178,171 @@
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
var l1 = document.getElementById('btn-1')
var l2 = document.getElementById('btn-2')
var l3 = document.getElementById('btn-3')
var l4 = document.getElementById('btn-4')
var l5 = document.getElementById('btn-5')
var l6 = document.getElementById('btn-6')
var l7 = document.getElementById('btn-7')
var content1 = document.getElementById('panel-1')
var content2 = document.getElementById('panel-2')
var content3 = document.getElementById('panel-3')
var content4 = document.getElementById('panel-4')
var content5 = document.getElementById('panel-5')
var content6 = document.getElementById('panel-6')
var content7 = document.getElementById('panel-7')
l1.onclick = function () {
{#this.className = 'active'#}
content7.className=''
content1.className = 'active'
l7.className=''
l2.className = ''
content7.className='tab-pane'
content2.className = 'tab-pane'
l5.className = ''
content5.className = 'tab-pane'
<script>function send_message() {
{% if user.can(Permission.ACTIVITY) %}
l4.className = ''
content4.className = 'tab-pane'
{% else %}
l3.className = ''
content3.className = 'tab-pane'
l6.className = ''
content6.className = 'tab-pane'
{% endif %}
console.log('hello');
$.ajax({
url: '/send_message/' + '{{ user.username }}' + '/' + $('#input-text-value').val(),
type: 'GET',
success: function (data) {
alert('Message sent successfully');
location.reload();
}
});
}
var l1 = document.getElementById('btn-1')
var l2 = document.getElementById('btn-2')
var l3 = document.getElementById('btn-3')
var l4 = document.getElementById('btn-4')
var l5 = document.getElementById('btn-5')
var l6 = document.getElementById('btn-6')
var l7 = document.getElementById('btn-7')
var content1 = document.getElementById('panel-1')
var content2 = document.getElementById('panel-2')
var content3 = document.getElementById('panel-3')
var content4 = document.getElementById('panel-4')
var content5 = document.getElementById('panel-5')
var content6 = document.getElementById('panel-6')
var content7 = document.getElementById('panel-7')
l1.onclick = function () {
{#this.className = 'active'#}
content7.className = ''
content1.className = 'active'
l7.className = ''
l2.className = ''
content7.className = 'tab-pane'
content2.className = 'tab-pane'
l5.className = ''
content5.className = 'tab-pane'
}
{% if user.can(Permission.ACTIVITY) %}
l4.className = ''
content4.className = 'tab-pane'
{% else %}
l3.className = ''
content3.className = 'tab-pane'
l6.className = ''
content6.className = 'tab-pane'
{% endif %}
}
l7.onclick = function () {
{#this.className = 'active'#}
l7.onclick = function () {
{#this.className = 'active'#}
{#content1.className=''#}
content7.className = 'active'
content7.className = 'active'
l1.className=''
l2.className = ''
content2.className = 'tab-pane'
content1.className='tab-pane'
l5.className = ''
content5.className = 'tab-pane'
l1.className = ''
l2.className = ''
content2.className = 'tab-pane'
content1.className = 'tab-pane'
l5.className = ''
content5.className = 'tab-pane'
{% if user.can(Permission.ACTIVITY) %}
l4.className = ''
content4.className = 'tab-pane'
{% else %}
l3.className = ''
content3.className = 'tab-pane'
l6.className = ''
content6.className = 'tab-pane'
{% endif %}
}
{% if user.can(Permission.ACTIVITY) %}
l4.className = ''
content4.className = 'tab-pane'
{% else %}
l3.className = ''
content3.className = 'tab-pane'
l6.className = ''
content6.className = 'tab-pane'
{% endif %}
}
l2.onclick = function () {
this.className = 'active'
content2.className = 'active'
l1.className = ''
content1.className = 'tab-pane'
l5.className = ''
content5.className = 'tab-pane'
l2.onclick = function () {
{% if user.can(Permission.ACTIVITY) %}
l4.className = ''
content4.className = 'tab-pane'
{% else %}
l3.className = ''
content3.className = 'tab-pane'
l6.className = ''
content6.className = 'tab-pane'
{% endif %}
}
l5.onclick = function () {
this.className = 'active'
content5.className = 'active'
l1.className = ''
content1.className = 'tab-pane'
l2.className = ''
content2.className = 'tab-pane'
{% if user.can(Permission.ACTIVITY) %}
l4.className = ''
content4.className = 'tab-pane'
{% else %}
l3.className = ''
content3.className = 'tab-pane'
l6.className = ''
content6.className = 'tab-pane'
{% endif %}
}
{% if user.can(Permission.ACTIVITY) %}
l4.onclick = function () {
this.className = 'active'
content2.className = 'active'
content4.className = 'active'
l1.className = ''
content1.className = 'tab-pane'
l2.className = ''
content2.className = 'tab-pane'
l5.className = ''
content5.className = 'tab-pane'
{% if user.can(Permission.ACTIVITY) %}
l4.className = ''
content4.className = 'tab-pane'
{% else %}
l3.className = ''
content3.className = 'tab-pane'
l6.className = ''
content6.className = 'tab-pane'
{% endif %}
}
l5.onclick = function () {
{% else %}
l3.onclick = function () {
this.className = 'active'
content5.className = 'active'
content3.className = 'active'
l1.className = ''
content1.className = 'tab-pane'
l2.className = ''
content2.className = 'tab-pane'
{% if user.can(Permission.ACTIVITY) %}
l4.className = ''
content4.className = 'tab-pane'
{% else %}
l3.className = ''
content3.className = 'tab-pane'
l6.className = ''
content6.className = 'tab-pane'
{% endif %}
l5.className = ''
content5.className = 'tab-pane'
l6.className = ''
content6.className = 'tab-pane'
}
l6.onclick = function () {
this.className = 'active'
content6.className = 'active'
{% if user.can(Permission.ACTIVITY) %}
l4.onclick = function () {
this.className = 'active'
content4.className = 'active'
l1.className = ''
content1.className = 'tab-pane'
l2.className = ''
content2.className = 'tab-pane'
l5.className = ''
content5.className = 'tab-pane'
}
{% else %}
l3.onclick = function () {
this.className = 'active'
content3.className = 'active'
l1.className = ''
content1.className = 'tab-pane'
l2.className = ''
content2.className = 'tab-pane'
l5.className = ''
content5.className = 'tab-pane'
l6.className = ''
content6.className = 'tab-pane'
}
l6.onclick = function () {
this.className = 'active'
content6.className = 'active'
l1.className = 'tab-pane'
content1.className = 'tab-pane'
l2.className = 'tab-pane'
content2.className = 'tab-pane'
l3.className = ''
content3.className = 'tab-pane'
l5.className = ''
content5.className = 'tab-pane'
}
{% endif %}
l1.className = 'tab-pane'
content1.className = 'tab-pane'
l2.className = 'tab-pane'
content2.className = 'tab-pane'
l3.className = ''
content3.className = 'tab-pane'
l5.className = ''
content5.className = 'tab-pane'
}
{% endif %}
</script>

@ -0,0 +1,14 @@
from aip import AipContentCensor
""" 你的 APPID AK SK """
APP_ID = '11752086'
API_KEY = 'OfTS5Nkkbo3Qt9VuZlK0izao'
SECRET_KEY = 'sPUzVHGlHYCcqTxmcaZOINk2OOBMZlZI'
client = AipContentCensor(APP_ID, API_KEY, SECRET_KEY)
print(client.getVersion())
def check_text(text: str):
""" 调用文本审核接口 """
result = client.textCensorUserDefined(text)
return result

Binary file not shown.

@ -22,7 +22,12 @@ from geetest_config import GEETEST_ID, GEETEST_KEY, REDIS_HOST, REDIS_PORT, CYCL
from sdk.geetest_lib import GeetestLib
geetest_dict = {}
# 发送bypass请求获取bypass状态并进行缓存
def check_bypass_status():
response = ""
@ -41,17 +46,16 @@ def check_bypass_status():
geetest_dict[GEETEST_BYPASS_STATUS_KEY] = bypass_status
print("bypass状态已经获取并存入redis当前状态为-{}".format(bypass_status))
check_bypass_status()
@app.shell_context_processor
def make_shell_context():
return dict(db=db, User=User, Role=Role, Students=Students, Permission=Permission, Post=Post,
Comment=Comment, Like=Like, Notification=Notification, Transaction=Transaction, Activity=Activity)
# 从缓存中取出当前缓存的bypass状态(success/fail)
def get_bypass_cache():
bypass_status_cache = geetest_dict[GEETEST_BYPASS_STATUS_KEY]
@ -103,5 +107,7 @@ def favicon():
# admin.add_view(ModelView(Activity, db.session, name="Activities", endpoint="Activities"))
# admin.add_view(FileAdmin("."))
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')

@ -1 +1 @@
Generic single-database configuration.
Single-database configuration for Flask.

@ -11,7 +11,7 @@
# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic
keys = root,sqlalchemy,alembic,flask_migrate
[handlers]
keys = console
@ -34,6 +34,11 @@ level = INFO
handlers =
qualname = alembic
[logger_flask_migrate]
level = INFO
handlers =
qualname = flask_migrate
[handler_console]
class = StreamHandler
args = (sys.stderr,)

@ -1,8 +1,11 @@
from __future__ import with_statement
from alembic import context
from sqlalchemy import engine_from_config, pool
from logging.config import fileConfig
import logging
from logging.config import fileConfig
from flask import current_app
from alembic import context
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
@ -17,9 +20,10 @@ logger = logging.getLogger('alembic.env')
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
from flask import current_app
config.set_main_option('sqlalchemy.url',
current_app.config.get('SQLALCHEMY_DATABASE_URI'))
config.set_main_option(
'sqlalchemy.url',
str(current_app.extensions['migrate'].db.get_engine().url).replace(
'%', '%%'))
target_metadata = current_app.extensions['migrate'].db.metadata
# other values from the config, defined by the needs of env.py,
@ -41,7 +45,9 @@ def run_migrations_offline():
"""
url = config.get_main_option("sqlalchemy.url")
context.configure(url=url)
context.configure(
url=url, target_metadata=target_metadata, literal_binds=True
)
with context.begin_transaction():
context.run_migrations()
@ -65,21 +71,19 @@ def run_migrations_online():
directives[:] = []
logger.info('No changes in schema detected.')
engine = engine_from_config(config.get_section(config.config_ini_section),
prefix='sqlalchemy.',
poolclass=pool.NullPool)
connectable = current_app.extensions['migrate'].db.get_engine()
connection = engine.connect()
context.configure(connection=connection,
target_metadata=target_metadata,
process_revision_directives=process_revision_directives,
**current_app.extensions['migrate'].configure_args)
with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata,
process_revision_directives=process_revision_directives,
**current_app.extensions['migrate'].configure_args
)
try:
with context.begin_transaction():
context.run_migrations()
finally:
connection.close()
if context.is_offline_mode():
run_migrations_offline()

@ -1,240 +0,0 @@
"""empty message
Revision ID: d3c0f90744f6
Revises:
Create Date: 2020-05-26 15:21:36.410197
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'd3c0f90744f6'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('organizations',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('confirmed', sa.Boolean(), nullable=True),
sa.Column('name', sa.String(length=64), nullable=True),
sa.Column('teacher', sa.String(length=128), nullable=True),
sa.Column('leader_student', sa.String(length=128), nullable=True),
sa.Column('phone', sa.String(length=128), nullable=True),
sa.Column('college', sa.String(length=256), nullable=True),
sa.Column('email', sa.String(length=64), nullable=True),
sa.PrimaryKeyConstraint('id')
)
op.create_table('roles',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(length=64), nullable=True),
sa.Column('default', sa.Boolean(), nullable=True),
sa.Column('permissions', sa.Integer(), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
)
with op.batch_alter_table('roles', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_roles_default'), ['default'], unique=False)
op.create_table('students',
sa.Column('student_id', sa.Integer(), nullable=False),
sa.Column('id_number', sa.String(length=18), nullable=True),
sa.Column('confirmed', sa.Boolean(), nullable=True),
sa.Column('role_id', sa.Integer(), nullable=True),
sa.PrimaryKeyConstraint('student_id')
)
with op.batch_alter_table('students', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_students_role_id'), ['role_id'], unique=False)
op.create_table('users',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('ID_number', sa.Integer(), nullable=True),
sa.Column('student_id', sa.Integer(), nullable=True),
sa.Column('confirmed', sa.Boolean(), nullable=True),
sa.Column('email', sa.String(length=64), nullable=True),
sa.Column('username', sa.String(length=64), nullable=True),
sa.Column('password_hash', sa.String(length=128), nullable=True),
sa.Column('role_id', sa.Integer(), nullable=True),
sa.Column('grade', sa.String(length=4), nullable=True),
sa.Column('college', sa.String(length=64), nullable=True),
sa.Column('about_me', sa.Text(), nullable=True),
sa.Column('member_since', sa.DateTime(), nullable=True),
sa.Column('last_seen', sa.DateTime(), nullable=True),
sa.Column('avatar_hash', sa.String(length=32), nullable=True),
sa.Column('avatar_img', sa.String(length=120), nullable=True),
sa.ForeignKeyConstraint(['role_id'], ['roles.id'], ),
sa.PrimaryKeyConstraint('id')
)
with op.batch_alter_table('users', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_users_ID_number'), ['ID_number'], unique=True)
batch_op.create_index(batch_op.f('ix_users_email'), ['email'], unique=True)
batch_op.create_index(batch_op.f('ix_users_student_id'), ['student_id'], unique=True)
batch_op.create_index(batch_op.f('ix_users_username'), ['username'], unique=True)
op.create_table('Activity',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('timestamp', sa.DateTime(), nullable=True),
sa.Column('activity_name', sa.String(length=256), nullable=False),
sa.Column('activity_time', sa.DateTime(), nullable=False),
sa.Column('activity_place', sa.String(length=256), nullable=False),
sa.Column('activity_describe', sa.String(length=256), nullable=False),
sa.Column('Organizer', sa.String(length=256), nullable=False),
sa.Column('is_schoolAgree', sa.Boolean(), nullable=False),
sa.Column('is_invalid', sa.Boolean(), nullable=True),
sa.Column('important', sa.INTEGER(), nullable=True),
sa.Column('announcer_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['announcer_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
with op.batch_alter_table('Activity', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_Activity_timestamp'), ['timestamp'], unique=False)
op.create_table('follow',
sa.Column('follower_id', sa.Integer(), nullable=False),
sa.Column('followed_id', sa.Integer(), nullable=False),
sa.Column('timestamp', sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(['followed_id'], ['users.id'], ),
sa.ForeignKeyConstraint(['follower_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('follower_id', 'followed_id')
)
op.create_table('notification',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('username', sa.String(length=64), nullable=False),
sa.Column('action', sa.Text(), nullable=False),
sa.Column('object', sa.String(length=64), nullable=False),
sa.Column('object_id', sa.Integer(), nullable=True),
sa.Column('is_read', sa.Boolean(), nullable=True),
sa.Column('timestamp', sa.DateTime(), nullable=True),
sa.Column('receiver_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['receiver_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
with op.batch_alter_table('notification', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_notification_timestamp'), ['timestamp'], unique=False)
op.create_table('posts',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('title', sa.Text(), nullable=True),
sa.Column('body', sa.Text(), nullable=True),
sa.Column('body_html', sa.Text(), nullable=True),
sa.Column('timestamp', sa.DateTime(), nullable=True),
sa.Column('author_id', sa.Integer(), nullable=True),
sa.Column('important', sa.INTEGER(), nullable=True),
sa.Column('recent_activity', sa.DateTime(), nullable=True),
sa.Column('is_anonymous', sa.Boolean(), nullable=True),
sa.ForeignKeyConstraint(['author_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
with op.batch_alter_table('posts', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_posts_recent_activity'), ['recent_activity'], unique=False)
batch_op.create_index(batch_op.f('ix_posts_timestamp'), ['timestamp'], unique=False)
op.create_table('transaction',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('timestamp', sa.DateTime(), nullable=True),
sa.Column('item_name', sa.String(length=64), nullable=False),
sa.Column('item_describe', sa.Text(), nullable=False),
sa.Column('link', sa.Text(), nullable=False),
sa.Column('transaction_mode', sa.String(length=64), nullable=False),
sa.Column('is_sold', sa.Boolean(), nullable=True),
sa.Column('seller_WeChat', sa.Text(), nullable=False),
sa.Column('seller_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['seller_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
with op.batch_alter_table('transaction', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_transaction_timestamp'), ['timestamp'], unique=False)
op.create_table('collect',
sa.Column('collecter_id', sa.Integer(), nullable=False),
sa.Column('collected_transaction_id', sa.Integer(), nullable=False),
sa.Column('timestamp', sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(['collected_transaction_id'], ['transaction.id'], ),
sa.ForeignKeyConstraint(['collecter_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('collecter_id', 'collected_transaction_id')
)
op.create_table('comments',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('body', sa.Text(), nullable=True),
sa.Column('body_html', sa.Text(), nullable=True),
sa.Column('timestamp', sa.DateTime(), nullable=True),
sa.Column('disabled', sa.Boolean(), nullable=True),
sa.Column('author_id', sa.Integer(), nullable=True),
sa.Column('post_id', sa.Integer(), nullable=True),
sa.Column('is_anonymous', sa.Boolean(), nullable=True),
sa.Column('replied_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['author_id'], ['users.id'], ),
sa.ForeignKeyConstraint(['post_id'], ['posts.id'], ),
sa.ForeignKeyConstraint(['replied_id'], ['comments.id'], ),
sa.PrimaryKeyConstraint('id')
)
with op.batch_alter_table('comments', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_comments_timestamp'), ['timestamp'], unique=False)
op.create_table('likes',
sa.Column('liker_id', sa.Integer(), nullable=False),
sa.Column('liked_post_id', sa.Integer(), nullable=False),
sa.Column('timestamp', sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(['liked_post_id'], ['posts.id'], ),
sa.ForeignKeyConstraint(['liker_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('liker_id', 'liked_post_id')
)
op.create_table('want',
sa.Column('wanter_id', sa.Integer(), nullable=False),
sa.Column('wanted_Activity_id', sa.Integer(), nullable=False),
sa.Column('timestamp', sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(['wanted_Activity_id'], ['Activity.id'], ),
sa.ForeignKeyConstraint(['wanter_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('wanter_id', 'wanted_Activity_id')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('want')
op.drop_table('likes')
with op.batch_alter_table('comments', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_comments_timestamp'))
op.drop_table('comments')
op.drop_table('collect')
with op.batch_alter_table('transaction', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_transaction_timestamp'))
op.drop_table('transaction')
with op.batch_alter_table('posts', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_posts_timestamp'))
batch_op.drop_index(batch_op.f('ix_posts_recent_activity'))
op.drop_table('posts')
with op.batch_alter_table('notification', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_notification_timestamp'))
op.drop_table('notification')
op.drop_table('follow')
with op.batch_alter_table('Activity', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_Activity_timestamp'))
op.drop_table('Activity')
with op.batch_alter_table('users', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_users_username'))
batch_op.drop_index(batch_op.f('ix_users_student_id'))
batch_op.drop_index(batch_op.f('ix_users_email'))
batch_op.drop_index(batch_op.f('ix_users_ID_number'))
op.drop_table('users')
with op.batch_alter_table('students', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_students_role_id'))
op.drop_table('students')
with op.batch_alter_table('roles', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_roles_default'))
op.drop_table('roles')
op.drop_table('organizations')
# ### end Alembic commands ###

@ -1,5 +1,6 @@
alembic==1.7.5
arrow==1.2.1
baidu-aip==2.2.18.0
binaryornot==0.4.4
bleach==3.1.4
blinker==1.4
@ -33,6 +34,7 @@ Markdown==3.2.1
MarkupSafe==2.0.1
poyo==0.5.0
python-dateutil==2.8.2
python-dotenv==0.19.2
python-slugify==5.0.2
requests==2.26.0
six==1.16.0

Loading…
Cancel
Save