def scan_status_for_mentions(status, exclude=[], is_reply=False): mentions = mention_re.findall(status.message) to_notify_m = {} for mention in mentions: try: _user = sqla.session.query( sqlm.User).filter_by(login_name=mention)[0] if not _user.id in exclude: to_notify_m[mention] = _user except IndexError: continue if not is_reply: notification_msg = "mentioned you in a status update" notification_id = status.id else: notification_msg = "mentioned you in a status update reply" notification_id = status.status.id broadcast(to=list(to_notify_m.values()), category="mention", url="/status/" + str(notification_id), title=notification_msg, description=status.message, content=status, author=status.author)
def toggle_status_hide(status): try: status = sqla.session.query(sqlm.StatusUpdate).filter_by(id=status)[0] except: return abort(404) if current_user.is_admin != True or current_user.is_mod != True: return abort(404) if not status.hidden: if current_user != status.author: broadcast(to=[ status.author, ], category="status", url="/status/" + str(status.id), title="Your status update was hidden", description=status.message, content=status, author=current_user) broadcast(to=list( sqla.session.query(sqlm.User).filter_by(is_admin=True)), category="mod", url="/status/" + str(status.id), title="status update hidden", description=status.message, content=status, author=current_user) status.hidden = not status.hidden sqla.session.add(status) sqla.session.commit() return app.jsonify(url="/status/" + str(status.id))
def toggle_follow_blog(slug): try: blog = sqla.session.query(sqlm.Blog).filter_by(slug=slug)[0] except IndexError: sqla.session.rollback() return abort(404) if not current_user in blog.subscribers: blog.subscribers.append(current_user) broadcast(to=[ blog.author, ], category="followed", url="/blog/%s" % (str(blog.slug), ), title="followed blog %s" % (str(blog.name)), description="", content=blog, author=current_user) else: try: blog.subscribers.remove(current_user) except: pass try: sqla.session.add(blog) sqla.session.commit() except: sqla.session.rollback() return app.jsonify(url="/blog/%s" % (blog.slug))
def request_friendship(login_name): try: user = sqla.session.query( sqlm.User).filter_by(my_url=login_name.strip().lower())[0] except IndexError: abort(404) if current_user == user: return abort(404) if not current_user in user.rejected_friends(): if current_user not in user.pending_friends( ) and current_user not in user.friends(): friendship = sqlm.Friendship( user=current_user, friend=user, created=arrow.utcnow().datetime.replace(tzinfo=None), ) sqla.session.add(friendship) sqla.session.commit() broadcast(to=[ user, ], category="friend", url="/member/%s/friends" % (str(user.my_url)), title="sent you a friend request", description="", content=current_user, author=current_user) return app.jsonify(url="/member/" + str(user.my_url))
def toggle_follow_blog_entry(slug, entry_slug): try: blog = sqla.session.query(sqlm.Blog).filter_by(slug=slug)[0] except IndexError: sqla.session.rollback() return abort(404) try: entry = sqla.session.query(sqlm.BlogEntry).filter_by( blog=blog, slug=entry_slug)[0] except IndexError: sqla.session.rollback() return abort(404) if blog.privacy_setting == "you" and current_user != blog.author: return abort(404) elif blog.privacy_setting == "editors" and ( current_user != blog.author and current_user not in blog.editors): return abort(404) elif blog.privacy_setting == "members" and not current_user.is_authenticated: return abort(404) if not current_user in entry.subscribers: entry.subscribers.append(current_user) broadcast(to=[ entry.author, ], category="followed", url="/blog/%s/e/%s" % (str(blog.slug), str(entry.slug)), title="followed blog entry %s" % (str(entry.title)), description="", content=entry, author=current_user) else: try: entry.subscribers.remove(current_user) except: pass try: sqla.session.add(entry) sqla.session.commit() except: sqla.session.rollback() if not current_user in blog.subscribers: blog.subscribers.append(current_user) try: sqla.session.add(blog) sqla.session.commit() except: sqla.session.rollback() return app.jsonify(url="/blog/%s/e/%s" % (blog.slug, entry.slug))
def validate_user(login_name): try: user = sqla.session.query( sqlm.User).filter_by(my_url=login_name.strip().lower())[0] except IndexError: abort(404) if current_user.is_admin != True: return abort(404) user.validated = True user.new_user_token = "" user.new_user_token_date = None broadcast( to=sqla.session.query(sqlm.User).filter_by( banned=False, ).filter(sqlm.User.login_name != user.login_name) \ .filter(sqlm.User.hidden_last_seen > arrow.utcnow().replace(hours=-24).datetime.replace(tzinfo=None)) \ .all(), category="new_member", url="/member/"+str(user.my_url), title="joined the forum! Greet them!", description="", content=user, author=user ) broadcast(to=[ user, ], category="new_member", url="/category/welcome", title="Welcome! Click here to introduce yourself!", description="", content=user, author=user) sqla.session.add(user) sqla.session.commit() send_mail_w_template(send_to=[ user, ], template="manual_validation_welcome", subject="Welcome to %s!" % (app.get_site_config("core.site-name"), ), variables={ "_user": user, "address": app.config['BASE'] + "/sign-in" }) return app.jsonify(url="/member/" + str(user.my_url))
def boop_blog_entry_comment(slug, entry_slug, comment_id): try: blog = sqla.session.query(sqlm.Blog).filter_by(slug=slug)[0] except IndexError: sqla.session.rollback() return abort(404) if blog.privacy_setting == "you" and current_user != blog.author: return abort(404) elif blog.privacy_setting == "editors" and ( current_user != blog.author and current_user not in blog.editors): return abort(404) elif blog.privacy_setting == "members" and not current_user.is_authenticated: return abort(404) try: entry = sqla.session.query(sqlm.BlogEntry).filter_by( blog=blog, slug=entry_slug)[0] except IndexError: sqla.session.rollback() return abort(404) try: comment = sqla.session.query(sqlm.BlogComment).filter_by( blog=blog, id=comment_id, blog_entry=entry)[0] except IndexError: sqla.session.rollback() return abort(404) if current_user in comment.boops: comment.boops.remove(current_user) else: comment.boops.append(current_user) broadcast(to=[ comment.author, ], category="boop", url="/blog/%s/e/%s" % (str(blog.slug), str(entry.slug)), title="booped your blog comment on %s" % (str(entry.title)), description=comment.html, content=comment, author=current_user) sqla.session.add(comment) sqla.session.commit() return app.jsonify(success=True)
def toggle_follow_user(login_name): try: user = sqla.session.query( sqlm.User).filter_by(my_url=login_name.strip().lower())[0] except IndexError: return abort(404) if current_user == user: return abort(404) try: follow_preference = sqla.session.query(sqlm.FollowingUser) \ .filter_by( user=current_user, following=user )[0] sqla.session.delete(follow_preference) sqla.session.commit() except IndexError: follow_preference = sqlm.FollowingUser( user=current_user, following=user, created=arrow.utcnow().datetime.replace(tzinfo=None)) sqla.session.add(follow_preference) sqla.session.commit() broadcast(to=[ user, ], category="followed", url="/member/%s" % (str(user.my_url)), title="followed your profile", description="", content=user, author=current_user) return app.jsonify(url="/member/" + str(user.my_url))
def create_new_status(target): request_json = request.get_json(force=True) attached_to_user = False if target: try: target_user = sqla.session.query( sqlm.User).filter_by(login_name=target)[0] if target_user == current_user: return app.jsonify(error="No talking to yourself.") if (current_user in [ u.ignoring for u in target_user.ignored_users ]) and not current_user.is_admin: return app.jsonify(error="User has blocked you.") attached_to_user = target_user except IndexError: target_user = None else: target_user = None if len(request_json.get("message", "").strip()) == 0: return app.jsonify(error="Your status update is empty.") if len(request_json.get("message", "")) > 1000: return app.jsonify(error="Your status update is too long.") cleaner = ForumHTMLCleaner() # try: cleaner.escape(request_json.get("message", "").strip()) # except: # return abort(500) _html = request_json.get("message", "").strip() status = sqlm.StatusUpdate() if attached_to_user: status.attached_to_user = attached_to_user status.participants.append(attached_to_user) status.author = current_user status.message = _html status.participants.append(status.author) status.created = arrow.utcnow().datetime.replace(tzinfo=None) status.replies = 0 sqla.session.add(status) sqla.session.commit() if target_user: send_notify_to_users = [] broadcast(to=[ target_user, ], category="profile_comment", url="/status/" + str(status.id), title="commented on your profile", description=status.message, content=status, author=status.author) else: send_notify_to_users = [] for user in status.author.followed_by(): if target_user: if user == target_user: continue send_notify_to_users.append(user) broadcast(to=send_notify_to_users, category="user_activity", url="/status/" + str(status.id), title="created a status update", description=status.message, content=status, author=status.author) exclude_from_mention = [u.id for u in send_notify_to_users] if target_user: exclude_from_mention.append(target_user.id) scan_status_for_mentions(status, exclude_from_mention, is_reply=False) return app.jsonify(url="/status/" + str(status.id))
def make_status_update_reply(status): try: status = sqla.session.query(sqlm.StatusUpdate).filter_by(id=status)[0] except: return abort(404) if status.hidden == True and (current_user.is_admin != True or current_user.is_mod != True): return abort(404) if status.muted and current_user != status.author: return app.jsonify(error="This status update is silenced. Shhh!") if (current_user in [u.ignoring for u in status.author.ignored_users ]) and not current_user.is_admin: return app.jsonify(error="User has blocked you.") try: if not (current_user.is_admin or current_user.is_mod) and \ (sqla.session.query(sqlm.StatusUpdateUser). \ filter_by(status=status, author=current_user)[0].blocked): return app.jsonify( error="You have been blocked from this status update.") except IndexError: pass if status.locked: return app.jsonify(error="This status update is locked.") if status.get_comment_count() > 199: return app.jsonify(error="This status update is full!") request_json = request.get_json(force=True) if request_json.get("reply", "").strip() == "": return app.jsonify(error="Your status update is empty.") if len(request_json.get("reply", "")) > 1000: return app.jsonify(error="Your status update is too long.") cleaner = ForumHTMLCleaner() try: cleaner.escape(request_json.get("reply", "")) except: return abort(500) _html = request_json.get("reply", "").strip() user_last_comment = False for comment in status.comments: if comment.author == current_user: user_last_comment = comment if user_last_comment: difference = (arrow.utcnow().datetime - arrow.get(user_last_comment.created).datetime).seconds if difference < 2: return app.jsonify( error="Please wait %s seconds before you can reply again." % (2 - difference)) sc = sqlm.StatusComment() sc.created = arrow.utcnow().datetime.replace(tzinfo=None) sc.message = _html sc.author = current_user sc.status = status sqla.session.add(sc) sqla.session.commit() status.replies = status.get_comment_count() status.last_replied = arrow.utcnow().datetime.replace(tzinfo=None) sqla.session.add(status) sqla.session.commit() if not current_user in status.participants: status.participants.append(current_user) clean_html_parser = ForumPostParser() parsed_reply = {} parsed_reply["text"] = cleaner.escape(sc.message) parsed_reply["user_name"] = sc.author.display_name parsed_reply["user_avatar"] = sc.author.get_avatar_url("60") parsed_reply["user_avatar_x"] = sc.author.avatar_60_x parsed_reply["author_login_name"] = sc.author.my_url parsed_reply["user_avatar_y"] = sc.author.avatar_60_y parsed_reply["time"] = humanize_time(sc.created) send_notify_to_users = [] exclude_from_mention = [] for user in sqla.session.query( sqlm.StatusUpdateUser).filter_by(status=status).all(): if user.author == current_user: exclude_from_mention.append(user.author.id) continue if user.ignoring: exclude_from_mention.append(user.author.id) continue if user.author == status.author: exclude_from_mention.append(user.author.id) continue send_notify_to_users.append(user.author) exclude_from_mention.append(user.author.id) broadcast(to=send_notify_to_users, category="status", url="/status/" + str(status.id), title="replied to %s's status update" % (str(status.author.display_name), ), description=status.message, content=status, author=current_user) try: status_user = sqla.session.query(sqlm.StatusUpdateUser).filter_by( status=status, author=status.author)[0] except IndexError: status_user = None if current_user != status.author: if status_user == None: broadcast(to=[status.author], category="status", url="/status/" + str(status.id), title="replied to your status update", description=status.message, content=status, author=current_user) else: if not status_user.ignoring: broadcast(to=[status.author], category="status", url="/status/" + str(status.id), title="replied to your status update", description=status.message, content=status, author=current_user) scan_status_for_mentions(sc, exclude_from_mention, is_reply=True) return app.jsonify(newest_reply=parsed_reply, count=status.get_comment_count(), success=True)
def create_message(): request_json = request.get_json(force=True) if len(request_json.get("title", "").strip()) == 0: return app.jsonify(error="Please enter a title.") if request_json.get("text", "").strip() == "": return app.jsonify(error="Please enter actual text for your message.") if len(request_json.get("text", "")) > 50000: return app.jsonify(error="Your post is too large.") if request_json.get("to") == None or not len(request_json.get("to", [""])) > 0: return app.jsonify(error="Choose who should receive your message.") topic = sqlm.PrivateMessage() topic.title = request_json.get("title", "").strip()[:100] topic.count = 1 topic.author = current_user topic.created = arrow.utcnow().datetime.replace(tzinfo=None) topic.last_seen_by = {} sqla.session.add(topic) sqla.session.commit() message = sqlm.PrivateMessageReply() message.message = request_json.get("html", "").strip() message.author = current_user message.created = arrow.utcnow().datetime.replace(tzinfo=None) message.pm = topic message.pm_title = topic.title sqla.session.add(message) sqla.session.commit() topic.last_reply = message sqla.session.add(topic) sqla.session.commit() participant = sqlm.PrivateMessageUser(author=current_user, pm=topic) sqla.session.add(participant) sqla.session.commit() to_notify = [] for user_pk in request_json.get("to"): if user_pk == current_user.id: continue try: u = sqla.session.query(sqlm.User).filter_by(id=user_pk)[0] try: ignore_setting = sqla.session.query( sqlm.IgnoringUser).filter_by(user=u, ignoring=current_user)[0] if ignore_setting.block_pms and not current_user.is_admin: return app.jsonify( error="You can not send a message to %s." % (u.display_name, )) except IndexError: pass if u.banned: return app.jsonify( error="%s is banned, they will not receive your message." % (u.display_name, )) if current_user == u: return app.jsonify( error= "Stop talking to yourself! (Remove yourself from the \"to\" list.)" ) new_participant = sqlm.PrivateMessageUser(author=u, pm=topic) sqla.session.add(new_participant) sqla.session.commit() to_notify.append(u) except IndexError: continue broadcast(to=to_notify, category="pm", url="/messages/" + str(topic.id), title="sent you a message: " + str(topic.title), description=message.message, content=topic, author=message.author) return app.jsonify(url="/messages/" + str(topic.id))
def new_message_in_pm_topic(pk): try: topic = sqla.session.query(sqlm.PrivateMessage).filter_by(id=pk)[0] except IndexError: return abort(404) try: pm_user = sqla.session.query(sqlm.PrivateMessageUser).filter_by( pm=topic, author=current_user)[0] except IndexError: return abort(404) difference = (arrow.utcnow().datetime - arrow.get(topic.last_reply.created).datetime).seconds if difference < 10 and topic.last_reply.author == current_user: return app.jsonify( error="Please wait %s seconds before you can reply again." % (10 - difference)) request_json = request.get_json(force=True) if len(request_json.get("text", "")) > 50000: return app.jsonify(error="Your post is too large.") if request_json.get("text", "").strip() == "": return app.jsonify(error="Your post is empty.") non_left_or_blocked_users = sqla.session.query( sqlm.PrivateMessageUser).filter_by(pm=topic, exited=False, blocked=False).count() if non_left_or_blocked_users == 1: return app.jsonify( error= "There is only one participant in this private message. Don't talk to yourself. :)" ) cleaner = ForumHTMLCleaner() try: post_html = cleaner.clean(request_json.get("post", "")) except: return abort(500) message = sqlm.PrivateMessageReply() message.message = post_html message.author = current_user message.created = arrow.utcnow().datetime.replace(tzinfo=None) message.pm = topic message.pm_title = topic.title sqla.session.add(message) sqla.session.commit() topic.last_reply = message topic.count = topic.count + 1 sqla.session.add(topic) sqla.session.commit() clean_html_parser = ForumPostParser() parsed_post = {} parsed_post["created"] = humanize_time(message.created, "MMM D YYYY") parsed_post["modified"] = humanize_time(message.modified, "MMM D YYYY") parsed_post["html"] = clean_html_parser.parse(message.message, _object=message) parsed_post["user_avatar"] = message.author.get_avatar_url() parsed_post["user_avatar_x"] = message.author.avatar_full_x parsed_post["user_avatar_y"] = message.author.avatar_full_y parsed_post["user_avatar_60"] = message.author.get_avatar_url("60") parsed_post["user_avatar_x_60"] = message.author.avatar_60_x parsed_post["user_avatar_y_60"] = message.author.avatar_60_y parsed_post["user_title"] = message.author.title parsed_post["_id"] = message.id parsed_post["author_name"] = message.author.display_name parsed_post["author_login_name"] = message.author.my_url parsed_post["author_actual_login_name"] = message.author.login_name post_count = sqla.session.query( sqlm.PrivateMessageReply).filter_by(pm=topic).count() notify_users = [] for u in sqla.session.query(sqlm.PrivateMessageUser).filter_by(pm=topic): if u.author == message.author: continue if u.exited or u.blocked or u.ignoring: continue notify_users.append(u.author) broadcast(to=notify_users, category="pm", url="/messages/%s/page/1/post/%s" % (str(topic.id), str(message.id)), title="replied to %s" % (str(topic.title)), description=message.message, content=topic, author=message.author) return app.jsonify(newest_post=parsed_post, count=post_count, success=True)
def create_blog_comment(slug, entry_slug, page): try: blog = sqla.session.query(sqlm.Blog).filter_by(slug=slug)[0] except IndexError: sqla.session.rollback() return abort(404) try: page = int(page) except: return abort(500) if blog.privacy_setting == "you" and current_user != blog.author: return abort(404) elif blog.privacy_setting == "editors" and ( current_user != blog.author and current_user not in blog.editors): return abort(404) elif blog.privacy_setting == "members" and not current_user.is_authenticated: return abort(404) try: entry = sqla.session.query( sqlm.BlogEntry).filter_by(slug=entry_slug)[0] except IndexError: sqla.session.rollback() return abort(404) if (current_user in [u.ignoring for u in entry.author.ignored_users ]) and not current_user.is_admin: return app.jsonify(error="You cannot comment on this entry.") request_json = request.get_json(force=True) if request_json.get("text", "").strip() == "": return app.jsonify(no_content=True) if len(request_json.get("text", "")) > 50000: return app.jsonify(error="Your comment is too large.") cleaner = ForumHTMLCleaner() try: post_html = cleaner.clean(request_json.get("post", "")) except: return abort(500) new_blog_comment = sqlm.BlogComment() new_blog_comment.blog_entry = entry new_blog_comment.blog = blog new_blog_comment.author = current_user new_blog_comment.html = post_html new_blog_comment.created = arrow.utcnow().datetime.replace(tzinfo=None) new_blog_comment.hidden = False new_blog_comment.b_e_title = entry.title sqla.session.add(new_blog_comment) sqla.session.commit() max_pages = int(math.ceil(float(entry.comment_count()) / 10.0)) e = entry replies = reply_re.findall(new_blog_comment.html) to_notify = {} for reply_ in replies: try: to_notify[reply_] = sqla.session.query( sqlm.BlogComment).filter_by(id=reply_[0])[0].author except: continue broadcast(to=list(to_notify.values()), category="topic_reply", url="""/blog/%s/e/%s""" % (slug, entry.slug), title="replied to you in %s" % (str(entry.title)), description=new_blog_comment.html, content=new_blog_comment, author=new_blog_comment.author) mentions = mention_re.findall(new_blog_comment.html) to_notify_m = {} for mention in mentions: try: to_notify_m[mention] = sqla.session.query( sqlm.User).filter_by(login_name=mention)[0] except: continue broadcast(to=list(to_notify_m.values()), category="mention", url="""/blog/%s/e/%s""" % (slug, entry.slug), title="mentioned you in a comment on %s" % (str(entry.title)), description=new_blog_comment.html, content=new_blog_comment, author=new_blog_comment.author) broadcast(to=[ entry.author, ], category="blogcomments", url="""/blog/%s/e/%s/page/%s#comments""" % (slug, entry_slug, max_pages), title="commented on your blog entry %s" % (str(entry.title)), description=new_blog_comment.html, content=new_blog_comment, author=current_user) if entry.author != blog.author: broadcast(to=[ blog.author, ], category="blogcomments", url="""/blog/%s/e/%s/page/%s#comments""" % (slug, entry_slug, max_pages), title="commented on blog entry %s" % (str(entry.title)), description=new_blog_comment.html, content=new_blog_comment, author=current_user) _to_notify = [] for u in entry.subscribers: if u.id != current_user.id: _to_notify.append(u) if len(_to_notify) > 0: broadcast(to=_to_notify, category="blogcomments", url="""/blog/%s/e/%s/page/%s#comments""" % (slug, entry_slug, max_pages), title="commented on %s's blog entry %s" % (str(entry.author.display_name), str(entry.title)), description=new_blog_comment.html, content=new_blog_comment, author=current_user) return app.jsonify(success=True, url="""/blog/%s/e/%s/page/%s""" % (slug, entry_slug, max_pages))
def new_blog_entry(slug): try: blog = sqla.session.query(sqlm.Blog).filter_by(slug=slug)[0] except IndexError: sqla.session.rollback() return abort(404) if current_user != blog.author: if current_user not in blog.editors: return abort(404) form = BlogEntryForm(csrf_enabled=False) if form.validate_on_submit(): e = sqlm.BlogEntry() e.blog = blog e.title = form.title.data e.author = current_user e.slug = sqlm.find_blog_entry_slug(e.title, blog) e.draft = form.draft.data cleaner = ForumHTMLCleaner() try: e.html = cleaner.clean(form.entry.data) except: return abort(500) e.created = arrow.utcnow().datetime.replace(tzinfo=None) if e.draft == False: e.published = arrow.utcnow().datetime.replace(tzinfo=None) e.b_title = blog.name sqla.session.add(e) sqla.session.commit() entry = e if e.draft == False: blog.recent_entry = e sqla.session.add(blog) sqla.session.commit() for subscriber in blog.subscribers: e.subscribers.append(subscriber) sqla.session.add(e) sqla.session.commit() if entry.author != blog.author: broadcast(to=[ blog.author, ], category="blog", url="""/blog/%s/e/%s""" % (slug, entry.slug), title="posted %s on blog %s" % (str(entry.title), str(blog.name)), description=entry.html, content=entry, author=current_user) _to_notify = [] for u in blog.subscribers: if u.id != current_user.id: _to_notify.append(u) mentions = mention_re.findall(e.html) to_notify_m = {} for mention in mentions: try: to_notify_m[mention] = sqla.session.query( sqlm.User).filter_by(login_name=mention)[0] except: continue broadcast(to=list(to_notify_m.values()), category="mention", url="""/blog/%s/e/%s""" % (slug, entry.slug), title="mentioned you in blog %s" % (str(entry.title)), description=e.html, content=e, author=e.author) if len(_to_notify) > 0: broadcast(to=_to_notify, category="blog", url="""/blog/%s/e/%s""" % (slug, entry.slug), title="posted %s on blog %s" % (str(entry.title), str(blog.name)), description=entry.html, content=entry, author=current_user) return redirect("/blog/" + str(blog.slug)) return render_template("blogs/new_blog_entry.jade", form=form, blog=blog, page_title="New Blog Entry - %s" % (app.get_site_config("core.site-name"), ))
def approve_friend(user, friend): try: user = sqla.session.query( sqlm.User).filter_by(my_url=user.strip().lower())[0] except IndexError: abort(404) try: friend = sqla.session.query( sqlm.User).filter_by(my_url=friend.strip().lower())[0] except IndexError: abort(404) if current_user != friend: abort(404) try: friendship = sqlm.Friendship.query.filter_by(blocked=False, pending=True) \ .filter(sqlm.Friendship.user == user, sqlm.Friendship.friend == friend)[0] except IndexError: abort(404) friendship.pending = False try: follow_preference = sqla.session.query(sqlm.FollowingUser) \ .filter_by( user=user, following=friend )[0] except IndexError: follow_preference = sqlm.FollowingUser( user=user, following=friend, created=arrow.utcnow().datetime.replace(tzinfo=None)) sqla.session.add(follow_preference) sqla.session.commit() try: follow_preference = sqla.session.query(sqlm.FollowingUser) \ .filter_by( user=friend, following=user )[0] except IndexError: follow_preference = sqlm.FollowingUser( user=friend, following=user, created=arrow.utcnow().datetime.replace(tzinfo=None)) sqla.session.add(follow_preference) sqla.session.commit() broadcast(to=[ user, ], category="friend", url="/member/%s/friends" % (str(user.my_url)), title="approved your friend request", description="", content=friend, author=friend) sqla.session.add(friendship) sqla.session.commit() return app.jsonify(url="/member/" + str(friend.my_url) + "/friends")