コード例 #1
0
ファイル: passport.py プロジェクト: ujued/witalk
def home():
	if 'ol_user' not in session :
		return redirect('/login')
	conn = current_app.connect()
	user = conn.execute('select id,avatar,points,name,age,gender,signature,my_page,email, location, github_name from user where id=%d' % session['ol_user']['id']).first()
	conn.close()
	return render_template(g.tperfix + 'home.html', user = user)
コード例 #2
0
ファイル: svc_user.py プロジェクト: ujued/witalk
def signin():
	"""
	return 0 repeat signin
	return -1 offline
	return integer get points
	"""
	if 'ol_user' not in session:
		return -1
	uid = session['ol_user']['id']
	conn = current_app.connect()
	record = conn.execute('select * from signin_record where user_id=%d' % uid).first()
	nowd = datetime.now()
	nowdstr = nowd.strftime('%Y-%m-%d %H:%M:%S')
	if record:
		if nowd.date() == record.last_signin_date.date():
			return 0
		cz = nowd - record.last_signin_date
		if cz.seconds < 1440 * 60:
			if record.endless_days+1 > record.max_days:
				max_days = record.endless_days+1
			else:
				max_days = record.max_days
			conn.execute("update signin_record set endless_days=endless_days+1, last_signin_date='%s', max_days=%d where id=%d" % (nowdstr, max_days, record.id))
			update_points(+(4 + record.endless_days), trade_info = 'signin, %ddays' % (record.endless_days+1))
			return 4 + record.endless_days
		else:
			conn.execute("update signin_record set endless_days=1, last_signin_date='%s' where id=%d" % (nowdstr, record.id))
			update_points(+4, trade_info = 'signin')
			return 4
	else:
		conn.execute("insert into signin_record(user_id, endless_days, last_signin_date) values(%d, %d, '%s')" % (uid, 1, nowdstr))
		update_points(+4, trade_info = 'signin, first time')
		return 4
コード例 #3
0
ファイル: witalk.py プロジェクト: ujued/witalk
def reply(id):
    conn = current_app.connect()
    topic = conn.execute('select * from topic where id=%d' % id).first()
    if topic is None:
        return render_template('404.html')
    if 'ol_user' not in session:
        return redirect('/passport/login')
    content = request.form['content']
    param = {'content': content}
    user = session['ol_user']
    if content is None or len(content) < 1:
        message = '内容不能为空.'
    else:
        content, user_agent = filter_sql([
            content.replace('<', '&lt;').replace('>', '&gt;'),
            request.headers.get('User-Agent')
        ])
        count = conn.execute(
            "insert into answer(content, author_id, topic_id, user_agent) values('%s', %d, %d, '%s')"
            % (content, user['id'], id, user_agent)).rowcount
        if count == 1:
            svc_user.update_points(+1, trade_info='post a answer')
            forumid = str(topic.forum_id)
            ensure_recent_queue_when_reply(topic.id, forumid)
            new_answer_notify(content, topic.title, topic.id, conn)
            conn.close()
            return redirect('/t/%d' % id)
        else:
            message = '失败.'
    return render_template('reply.html',
                           message=message,
                           topic=topic,
                           param=param)
コード例 #4
0
ファイル: passport.py プロジェクト: ujued/witalk
def register():
	if request.method == 'GET':
		return render_template(g.tperfix + 'register.html')
	username = request.form['username']
	password = request.form['password']
	email = request.form['email']
	if username == None or len(username) < 1 or username.isdigit() or ' ' in username:
		message = '用户名只能由字母数字下划线构成, 且不能为纯数字!'
	elif password == None or len(password) < 6:
		message = "密码不能少于6位."
	elif email == None or len(email) < 8 or '@' not in email:
		message = 'Email是否正确?'
	else:
		conn = current_app.connect()
		username, email, password  = filter_sql([username, email, password])
		password = hashlib.md5(password.encode('utf-8')).hexdigest()
		user_from_db = conn.execute("select id from user where name='%s' or email='%s'" % (username, email)).first()
		if user_from_db == None :
			count = conn.execute("insert into user(name, password, email) values('%s', '%s', '%s')" % (username, password, email)).rowcount
			referee = request.args.get('r')
			if referee and conn.execute("select count(id) from user where `name`='%s'" % referee).first()[0] == 1:
				referee, = filter_sql([referee,])
				conn.execute("update user set referee= '%s', points=points+5 where `name`='%s'" % (referee, username))
				conn.execute("update user set points=points+5 where `name`='%s'" % referee)
			if count == 1:
				message = '注册成功 ^_^'
			else:
				message = '注册失败!'
		else:
			message = '你注册过啦!可以用邮箱找回凭证。'
		conn.close()
	return render_template(g.tperfix + 'register.html', message = message)
コード例 #5
0
ファイル: passport.py プロジェクト: ujued/witalk
def  login():
	if request.method == 'GET':
		if 'ol_user' in session:
			return redirect('/home')
		return render_template(g.tperfix + 'login.html')
	id = request.form['id']
	password = request.form['password']
	if id == None or len(id) < 1 :
		message = '帐号不能为空!'
	elif password == None or len(password) < 6:
		message = "密码不少与6位!"
	else:
		id, password = filter_sql([id, password])
		password = hashlib.md5(password.encode('utf-8')).hexdigest()
		conn = current_app.connect()
		if id.isdigit() :
			user_from_db = conn.execute("select * from user where id=%d  and password='******'" % (id, password)).first()
		else:
			user_from_db = conn.execute("select * from user where (name='%s' or email='%s') and password='******'" % (id, id, password)).first()
		conn.close()
		if user_from_db == None:
			message = '帐号或密码错误!'
		else:
			session['ol_user'] = create_user_dict(user_from_db)
			backurl= request.args.get('back')
			if backurl:
				return redirect(backurl)
			return redirect('/home')
	return render_template(g.tperfix + 'login.html', message = message)
コード例 #6
0
ファイル: passport.py プロジェクト: ujued/witalk
def chpasswd():
	if 'ol_user' not in session:
		return redirect('/login')
	oldpasswd = request.form['oldpasswd']
	newpasswd = request.form['newpasswd']
	renewpasswd = request.form['renewpasswd']
	oldpasswd, newpasswd, renewpasswd = filter_sql([oldpasswd, newpasswd, renewpasswd])
	if oldpasswd != None and len(oldpasswd) >= 6 and newpasswd != None and renewpasswd != None and len(newpasswd) >= 6 and len(renewpasswd) >= 6:
		if newpasswd == renewpasswd:
			conn = current_app.connect()
			uid = session['ol_user']['id']
			if hashlib.md5(oldpasswd.encode('utf-8')).hexdigest() != conn.execute('select password from user where id=%d' % uid).first()[0]:
				flash('修改失败,密码错误!')
				conn.close()
				return redirect('/home')
			newpasswd = hashlib.md5(newpasswd.encode('utf-8')).hexdigest()
			count = conn.execute("update user set `password`='%s' where id=%d" % (newpasswd, uid)).rowcount
			conn.close()
			if count == 1:
				session.pop('ol_user', None)
				flash('修改成功!请重新登录.')
				return redirect('/login')
			else:
				return 'error.'
		else:
			flash('两次新密码不一致!')
			return redirect('/home')
	else:
		flash('安全起见,密码不得少于6位!')
		return redirect('/home')
コード例 #7
0
ファイル: witalk.py プロジェクト: ujued/witalk
def rtopics(cate):
    sql = 'select * from topic where id=null'
    if cate == 'all':
        for id in current_app.all_recent_topic_ids:
            sql += ' union select * from topic where id=%d' % id
    elif cate == 'programming':
        for id in current_app.programming_recent_topic_ids:
            sql += ' union select * from topic where id=%d' % id
    elif cate == 'art':
        for id in current_app.art_recent_topic_ids:
            sql += ' union select * from topic where id=%d' % id
    elif cate == 'trade':
        for id in current_app.trade_recent_topic_ids:
            sql += ' union select * from topic where id=%d' % id
    elif cate == 'paid':
        for id in current_app.paid_recent_topic_ids:
            sql += ' union select * from topic where id=%d' % id
    else:
        return jsonify([])
    conn = current_app.connect()
    dumps_topics = []
    row = conn.execute(sql).fetchall()
    for t1 in row:
        dumps_topics.append(create_recent_topic_item(t1, conn))
    return jsonify(dumps_topics)
コード例 #8
0
def send_message():
	if 'ol_user' not in session:
		return redirect('/login?back=/msgsend')
	if request.method == 'GET':
		to_user = ''
		if request.args.get('to'):
			to_user = request.args.get('to')
			import urllib
			to_user = urllib.parse.unquote(to_user)
			if "'" in to_user:
				return render_template(g.tperfix + '404.html')
		return render_template(g.tperfix + 'msgsend.html', to_user = to_user)
	user = session['ol_user']
	to_user = request.form['username']
	msg_content = request.form['content']
	if to_user is None or msg_content is None or len(msg_content) < 1:
		return render_template(g.tperfix + 'msgsend.html', message = '接收者不能为空,信息内容不能为空!')
	if to_user == user['name']:
		return render_template(g.tperfix + 'msgsend.html', message = '不能给自己发信息!')
	to_user, msg_content = filter_sql([to_user, msg_content])
	conn = current_app.connect()
	to_id_row = conn.execute("select id from user where name='%s'" % to_user).first()
	if not to_id_row:
		message = '接收者不存在!'
	else:
		count = conn.execute("insert into message(content, from_id, to_id) values('%s', %d, %d)" % (msg_content, user['id'], to_id_row.id)).rowcount
		if count == 1:
			message = '已发送!'
		else:
			message = 'Error.'
	conn.close()
	return render_template(g.tperfix + 'msgsend.html', message = message)
コード例 #9
0
ファイル: passport.py プロジェクト: ujued/witalk
def profile_name(username):
	import urllib
	username = urllib.parse.unquote(username)
	if "'" in username:
		return render_template(g.tperfix + '404.html')
	conn = current_app.connect()
	id = conn.execute("select id from user where name='%s'" % username).first()
	if id : return profile(id[0])
	else : return render_template(g.tperfix + '404.html')
コード例 #10
0
ファイル: nav.py プロジェクト: ujued/witalk
def pictures():
    if 'ol_user' not in session:
        return redirect('/login?back=/pictures')
    conn = current_app.connect()
    pictures = conn.execute("select * from picture where author_id = %d" %
                            session['ol_user']['id']).fetchall()
    conn.close()
    pictures.reverse()
    return render_template(g.tperfix + 'pictures.html', pictures=pictures)
コード例 #11
0
ファイル: entry.py プロジェクト: ujued/witalk
 def t_wrapper(*args):
     conn = current_app.connect()
     conn.begin()
     try:
         result = func(*args)
         conn.commit()
     except Exception as e:
         conn.rollback()
         flash(e)
         return render_template('404.html'), 404
     return result
コード例 #12
0
ファイル: svc_user.py プロジェクト: ujued/witalk
def administrator(uid=None):
	"""
	return boolean
	"""
	if not uid:
		if 'ol_user' in session : uid = session['ol_user']['id']
		else : return False
	conn = current_app.connect()
	count = conn.execute('select count(id) from administrator where author_id=%d and forum_id=0' % uid).first()[0]
	if count >= 1 : return True
	else : return False
コード例 #13
0
ファイル: witalk.py プロジェクト: ujued/witalk
def forums():
    conn = current_app.connect()
    forum_count = conn.execute('select count(id) from forum').first()[0]
    topic_count = conn.execute('select count(id) from topic').first()[0]
    trash_topic_count = conn.execute(
        'select count(id) from topic_trash').first()[0]
    conn.close()
    return render_template(g.tperfix + 'forums.html',
                           forum_count=forum_count,
                           topic_count=topic_count,
                           trash_topic_count=trash_topic_count)
コード例 #14
0
def send_messages():
	if 'ol_user' not in session:
		return redirect('/login?back=/msgbox/all')
	user = session['ol_user']
	conn = current_app.connect()
	send_messages = conn.execute('select * from message where from_id=%d and (first_del_id is null or first_del_id<>%d)' % (user['id'], user['id'])).fetchall()
	messages = []
	for message in send_messages:
		messages.append(create_message_item(message, conn))
	conn.close()
	messages.reverse()
	return render_template(g.tperfix + 'msgbox.html', noreply = True, send = True, messages = messages, title = '发件箱 • <a href="/msgbox">未读信息</a>&nbsp;&nbsp;<a href="/msgbox/all">收件箱</a>')
コード例 #15
0
ファイル: witalk.py プロジェクト: ujued/witalk
def view(id):
    conn = current_app.connect()
    topic = conn.execute(
        'select topic.id,view_count,topic.user_agent,topic.post_date,title,price,content,user.name author_name,user.avatar author_avatar, user.id author_id, forum.name forum_name, forum.id forum_id from topic left join user on topic.author_id = user.id left join forum  on topic.forum_id = forum.id where topic.id=%d'
        % id).first()
    if topic is None:
        flash('主题不存在,可能因违法被回收!')
        return render_template(g.tperfix + '404.html')
    conn.execute('update topic set view_count=view_count+1 where id=%d' %
                 id)  # view_count
    answer_count = conn.execute(
        'select count(id) from answer where topic_id=%d' % topic.id).first()[0]
    last_answer_info_row = conn.execute(
        'select author_id, post_date from answer where topic_id=%d order by post_date desc limit 1'
        % topic.id).first()
    if not last_answer_info_row:
        last_answer_info = None
    else:
        last_answer_author = conn.execute(
            'select id, name from user where id=%d' %
            last_answer_info_row.author_id).first()
        last_answer_info = {
            'author_name': last_answer_author.name,
            'author_id': last_answer_author.id,
            'post_date': last_answer_info_row.post_date
        }
    collect_count = conn.execute(
        "select count(id) from collection where collect_id=%d and collect_cate='t'"
        % id).first()[0]
    auth_operate = check_topic_append(id, conn)
    auth_operate += check_auth_topic(id, topic.forum_id, conn)
    appends_row = conn.execute('select * from append_topic where topic_id=%d' %
                               id)
    appends = []
    for append_row in appends_row:
        appends.append(create_append_item(append_row, conn))

    paymentIsOK = False
    if 'ol_user' in session and topic.price > 0:
        count = conn.execute(
            "select count(id) from bag where user_id=%d and goods_name='topic' and goods_id=%d"
            % (session['ol_user']['id'], id)).first()[0]
        if count == 1:
            paymentIsOK = True
    return render_template(g.tperfix + 'topic.html',
                           topic=topic,
                           answer_count=answer_count,
                           collect_count=collect_count,
                           last_answer_info=last_answer_info,
                           auth_operate=auth_operate,
                           appends=appends,
                           paymentIsOK=paymentIsOK)
コード例 #16
0
def read_messages():
	if 'ol_user' not in session:
		return redirect('/login?back=/msgbox')
	user = session['ol_user']
	conn = current_app.connect()
	read_messages = conn.execute('select * from message where to_id=%d and readed=0 and (first_del_id is null or first_del_id<>%d)' % (user['id'], user['id'])).fetchall()
	conn.execute('update message set readed=1 where to_id=%d and readed=0' % user['id'])
	messages = []
	for message in read_messages:
		messages.append(create_message_item(message, conn))
	conn.close()
	messages.reverse()
	return render_template(g.tperfix + 'msgbox.html', receive = True, messages = messages, title='未读信息 • <a href="/msgbox/all">收件箱</a>&nbsp;&nbsp;<a href="/msgbox/send">发件箱</a>')
コード例 #17
0
def noncollect(cate, id, uid=None):
    """
    return boolean
    """
    if not uid:
        if 'ol_user' in session: uid = session['ol_user']['id']
        else: return False
    conn = current_app.connect()
    count = conn.execute(
        "delete from collection where collect_cate='%s' and collect_id=%d and owner_id=%d"
        % (cate, id, uid)).rowcount
    if count >= 1: flash('取消收藏!')
    else: return flash('失败!')
コード例 #18
0
ファイル: svc_user.py プロジェクト: ujued/witalk
def check_bag(goods_name, goods_id, uid=None):
	"""
	return boolean
	"""
	if not uid:
		if 'ol_user' in session:
			uid = session['ol_user']['id']
		else:
			return False
	conn = current_app.connect()
	count = conn.execute("select count(id) from bag where goods_name='%s' and goods_id=%d" % (goods_name, goods_id)).first()[0]
	if count == 1:
		return True
	return False
コード例 #19
0
def collected(cate, id):
    """
    return boolean
    """
    if 'ol_user' not in session:
        return False
    uid = session['ol_user']['id']
    conn = current_app.connect()
    count = conn.execute(
        "select count(id) from collection where owner_id=%d and collect_cate='%s' and collect_id=%d"
        % (uid, cate, id)).first()[0]
    if count == 1:
        return True
    return False
コード例 #20
0
ファイル: witalk.py プロジェクト: ujued/witalk
def post(id):
    conn = current_app.connect()
    count = conn.execute('select count(id) from forum where id=%d' %
                         id).first()[0]
    if count == 0:
        return render_template('404.html')
    forum = conn.execute('select id, name from forum where id=%d ' %
                         id).first()
    if 'ol_user' not in session:
        return redirect('/login?back=/new/%d' % id)
    if request.method == 'GET':
        return render_template(g.tperfix + 'new.html', param=None, forum=forum)
    user = session['ol_user']
    title = request.form['title']
    content = request.form['content']
    price = request.form.get('price', '0')
    if not price.isdigit():
        price = 0
    else:
        price = int(price)
    param = {'title': title, 'content': content, 'price': price}
    if title is None or len(title) < 4:
        message = '标题不能少与4字!'
    elif len(title) < 8 and (content is None or len(content) < 12):
        message = '标题少与8字时, 内容不能少于12字!'
    else:
        title, content, user_agent = filter_sql(
            [title, content, request.headers.get('User-Agent')])
        count = conn.execute("select count(id) from topic where title='%s'" %
                             title).first()[0]
        if count != 0:
            message = '这篇主题发表过了!'
        else:
            rowcount = conn.execute(
                "insert into topic(title, content, author_id, forum_id, user_agent, price) values('%s', '%s', %d, %d, '%s', %d)"
                % (title, content, user['id'], id, user_agent, price)).rowcount
            if rowcount == 1:
                svc_user.update_points(+2, trade_info='post a topic')
                # recent topics
                topic_id = conn.execute(
                    "select id from topic where title='%s'" % title).first()[0]
                ensure_recent_queue_when_post(topic_id, str(id))
                new_topic_notify(content, title, topic_id, conn)
                message = '创建成功!'
            else:
                message = '失败!'
    return render_template(g.tperfix + 'new.html',
                           message=message,
                           param=param,
                           forum=forum)
コード例 #21
0
ファイル: witalk.py プロジェクト: ujued/witalk
def answers(id, pid):
    conn = current_app.connect()
    count = conn.execute('select count(id) from answer where topic_id=%d' %
                         id).first()[0]
    page_info = page_turning_info(count, pid)
    if not page_info['have']:
        conn.close()
        return 'None'
    answers = conn.execute('select * from answer where topic_id=%d limit %s' %
                           (id, page_info['limit'])).fetchall()
    json_answers = []
    for answer in answers:
        json_answers.append(create_answer_item(answer, conn))
    conn.close()
    return json.dumps(json_answers, ensure_ascii=False)
コード例 #22
0
ファイル: nav.py プロジェクト: ujued/witalk
def upload():
    if 'ol_user' not in session:
        return redirect('/login?back=/upload')
    if request.method == 'GET':
        return render_template(g.tperfix + 'upload.html')
    file = request.files['image']
    filename = str(time.time())
    filename += ('.' + file.filename.split('.')[-1])
    file.save("/opt/witalk/images/" + filename)
    conn = current_app.connect()
    conn.execute(
        "insert into picture (name, author_id, size) value('%s', %d)" %
        (filename, session['ol_user']['id']))
    conn.close()
    return render_template(g.tperfix + 'upload.html', filename=filename)
コード例 #23
0
def msgdel(id):
	if 'ol_user' not in session:
		return redirect('/login')
	user = session['ol_user']
	conn = current_app.connect()
	first_del_id = conn.execute('select first_del_id from message where id=%d and (from_id=%d or to_id=%d)' % (id, user['id'], user['id'])).first()[0]
	if first_del_id and (first_del_id != user['id']):
		conn.execute('delete from message where id=%d' % id)
	else:
		conn.execute('update message set first_del_id=%d where id=%d and (from_id=%d or to_id=%d)' % (user['id'], id, user['id'], user['id']))
	flash('已删除!')
	backurl = request.args.get('back')
	if backurl:
		return redirect(backurl)
	return redirect('/msgbox/all')
コード例 #24
0
ファイル: svc_user.py プロジェクト: ujued/witalk
def points(uid=None):
	""" 
	get uid's T points
	"""
	if not uid:
		if 'ol_user' in session:
			uid = session['ol_user']['id']
		else:
			return 0
	conn = current_app.connect()
	value = conn.execute('select points from user where id=%d' % uid).first()
	if value:
		return value[0]
	else:
		return 0
コード例 #25
0
ファイル: witalk.py プロジェクト: ujued/witalk
def _list(id):
    conn = current_app.connect()
    forum = conn.execute('select * from forum where id=%d' % id).first()
    topic_count = conn.execute(
        'select count(id) from topic where forum_id=%d' % id).first()[0]
    if forum is None:
        return render_template('404.html')
    collected = False
    if 'ol_user' in session:
        if conn.execute(
                "select count(id) from collection where collect_cate='f' and collect_id=%d and owner_id=%d"
                % (id, session['ol_user']['id'])).first()[0] != 0:
            collected = True
    return render_template(g.tperfix + 'forum.html',
                           forum=forum,
                           topic_count=topic_count)
コード例 #26
0
ファイル: witalk.py プロジェクト: ujued/witalk
def own_answers(uid, pid):
    conn = current_app.connect()
    count = conn.execute("select count(id) from answer where author_id=%d" %
                         uid).first()[0]
    page_info = page_turning_info(count, pid)
    if not page_info['have']:
        conn.close()
        return 'None'
    answers = conn.execute('select * from answer where author_id=%d limit %s' %
                           (uid, page_info['limit'])).fetchall()
    json_answers = []
    for answer in answers:
        json_answers.append(create_own_answer_item(answer, conn))
    conn.close()
    json_answers.reverse()
    return jsonify(json_answers)
コード例 #27
0
ファイル: svc_user.py プロジェクト: ujued/witalk
def check_password(password, uid=None):
	"""
	return boolean
	"""
	if not uid:
		if 'ol_user' in session:
			uid = session['ol_user']['id']
		else:
			return False
	conn = current_app.connect()
	password_row = conn.execute('select password from user where id=%d' % uid).first()
	password = hashlib.md5(password.encode('utf-8')).hexdigest()
	if password_row and password_row[0] == password:
		return True
	else:
		return False
コード例 #28
0
def collect(cate, id, uid=None):
    """
    return None
    """
    if not uid:
        if 'ol_user' in session:
            uid = session['ol_user']['id']
        else:
            return
    conn = current_app.connect()
    count = conn.execute(
        "select count(id) from collection where collect_cate='%s' and owner_id=%d and collect_id=%d"
        % (cate, uid, id)).first()[0]
    if count == 0:
        count = conn.execute(
            "insert into collection(collect_cate, collect_id, owner_id) values('%s', %d, %d)"
            % (cate, id, uid)).rowcount
        if count == 1: flash('收藏成功!')
        else: flash('收藏失败!')
    else: flash('已收藏!')
コード例 #29
0
ファイル: collection.py プロジェクト: ujued/witalk
def collections():
    if 'ol_user' not in session:
        return redirect('/login?back=/collections')
    user = session['ol_user']
    conn = current_app.connect()
    f_collections_row = conn.execute(
        "select * from collection where collect_cate='f' and owner_id=%d" %
        user['id']).fetchall()
    t_collections_row = conn.execute(
        "select * from collection where collect_cate='t' and owner_id=%d" %
        user['id']).fetchall()
    f_collections = []
    t_collections = []
    for collection in f_collections_row:
        f_collections.append(create_f_collection_item(collection, conn))
    for collection in t_collections_row:
        t_collections.append(create_t_collection_item(collection, conn))
    f_collections.reverse()
    t_collections.reverse()
    return render_template(g.tperfix + 'collections.html',
                           f_collections=f_collections,
                           t_collections=t_collections)
コード例 #30
0
ファイル: witalk.py プロジェクト: ujued/witalk
def mytopics(uid, pid):
    json_topics = []
    conn = current_app.connect()
    count = conn.execute('select count(id) from topic where author_id=%d' %
                         uid).first()[0]
    if count == 0:
        return 'None'
    page_count = request.args.get('count')
    if page_count:
        page_info = page_turning_info(count, pid, int(page_count))
    else:
        page_info = page_turning_info(count, pid)

    if not page_info['have']:
        return 'None'
    sql = 'select * from topic where author_id=%d limit %s' % (
        uid, page_info['limit'])
    topics = conn.execute(sql).fetchall()
    topics.reverse()
    for topic in topics:
        json_topics.append(create_topic_item(topic, conn))
    return jsonify(json_topics)