def user_profile_projects(username): user = User.get_by_name(username) if not user: abort(404) if not user.sign_up_complete: abort(404) current_user_is_friend_with_user = current_user.is_friend_with(user.id) projects = [] for project in user.projects.order_by(Project.name): if current_user.id == user.id \ or project.visibility == "public" \ or (project.visibility == "friends" and current_user_is_friend_with_user) \ or (project.visibility == "private" and current_user.is_project_collaborator_of(project.id)): projects.append({ "name": project.name, "link": f"/{project.owner_name}/{project.name}", "desc": project.project_desc }) if current_user.id == user.id: return render_template( "user_profile_projects.html.j2", user_id=user.id, user_profile_pic_url=user.avatar_url, username=username, useremail=user.email, userprofile_desc=user.profile_desc, token=user.set_token(), projects=projects, current_user_is_friend_with_user=current_user_is_friend_with_user) elif not user.private or current_user_is_friend_with_user: if user.email_private: return render_template("user_profile_projects.html.j2", user_id=user.id, user_profile_pic_url=user.avatar_url, username=username, userprofile_desc=user.profile_desc, projects=projects, current_user_is_friend_with_user= current_user_is_friend_with_user) return render_template( "user_profile_projects.html.j2", user_id=user.id, user_profile_pic_url=user.avatar_url, username=username, useremail=user.email, userprofile_desc=user.profile_desc, projects=projects, current_user_is_friend_with_user=current_user_is_friend_with_user) abort(404)
def user_profile_friends(username): user = User.get_by_name(username) if not user: abort(404) if not user.sign_up_complete: abort(404) current_user_is_friend_with_user = current_user.is_friend_with(user.id) friends = [] for friend in db.session.query(User)\ .filter(User.id.in_(db.session.query(Friendship.friend_id).filter_by(user_id=user.id)))\ .with_entities(User.name, User.small_avatar_url): friends.append({ "name": friend.name, "link": f"/{friend.name}", "picUrl": friend.small_avatar_url }) if current_user.id == user.id: return render_template( "user_profile_friends.html.j2", user_id=user.id, user_profile_pic_url=user.avatar_url, username=username, useremail=user.email, userprofile_desc=user.profile_desc, token=user.set_token(), friends=friends, current_user_is_friend_with_user=current_user_is_friend_with_user) elif not user.private or current_user_is_friend_with_user: if user.email_private: return render_template("user_profile_friends.html.j2", user_id=user.id, user_profile_pic_url=user.avatar_url, username=username, userprofile_desc=user.profile_desc, friends=friends, current_user_is_friend_with_user= current_user_is_friend_with_user) return render_template( "user_profile_friends.html.j2", user_id=user.id, user_profile_pic_url=user.avatar_url, username=username, useremail=user.email, userprofile_desc=user.profile_desc, friends=friends, current_user_is_friend_with_user=current_user_is_friend_with_user) abort(404)
def on_add_friend_to_chat_group(data): current_user_member_link = ChatGroupMemberLink.query.filter_by(user_id=current_user.id, chat_group_id=data["chatGroupId"]) \ .first() if not current_user_member_link or current_user_member_link.user_role != "admin": return friend = User.get_by_name_or_email(data["friendNameOrEmail"]) if not friend \ or ChatGroupMemberLink.query.filter_by(user_id=friend.id, chat_group_id=data["chatGroupId"]).scalar()\ or not current_user.is_friend_with(friend.id): emit("add_friend_to_chat_group_error_invalid_target", room=current_user.id) return chat_group = ChatGroup.query.filter_by(id=data["chatGroupId"]).first() db.session.add(ChatGroupMemberLink(data["chatGroupId"], friend.id, "default")) db.session.commit() member_ids_to_emit_new_chat_group_member_info_to = [] members = {} for member_user in db.session.query(ChatGroupMemberLink) \ .filter_by(chat_group_id=chat_group.id) \ .join(User, User.id == ChatGroupMemberLink.user_id)\ .with_entities(User.id, User.name, User.small_avatar_url, ChatGroupMemberLink.user_role): members[member_user.id] = { "id": member_user.id, "name": member_user.name, "picUrl": member_user.small_avatar_url, "goToUrl": f"/{member_user.name}", "role": member_user.user_role } if member_user.id != friend.id: member_ids_to_emit_new_chat_group_member_info_to.append(member_user.id) last_msg = friend.get_last_msg(chat_group.id, "chatGroup") emit("new_chat_group", {"id": chat_group.id, "type": "chatGroup", "name": chat_group.name, "unreadCount": friend.get_unread_count_in_chat(chat_group.id, "chatGroup"), "lastMsg": {"content": last_msg.content, "datetime": f"{last_msg.datetime}+00:00"} if last_msg else "None", "picUrl": "/static/img/group.png", "roleOfCurrentUser": "******", "members": members}, room=friend.id) for id_ in member_ids_to_emit_new_chat_group_member_info_to: emit("new_chat_group_member", {"chatGroupId": chat_group.id, "chatGroupType": "chatGroup", "member": {"id": friend.id, "name": friend.name, "picUrl": friend.small_avatar_url, "goToUrl": f"/{friend.name}", "role": "default"} }, room=id_) emit("successfully_added_friend_to_chat_group", room=current_user.id)
def on_send_msg(data): if data["chatType"] == "userToUser": if not current_user.is_friend_with(data["chatId"]): return msg = Msg(current_user.id, data["chatId"], data["content"]) db.session.add(msg) db.session.commit() msg_data_to_emit = {"id": msg.id, "type": "msg", "chatType": "userToUser", "picUrl": current_user.small_avatar_url, "goToUrl": f"/{current_user.name}", "goToChatUrl": f"/chat?with{current_user.name}", "fromId": msg.from_id, "fromName": current_user.name, "toId": msg.to_id, "content": msg.content, "datetime": f"{msg.datetime}+00:00"} receiver_user_ids = [msg.to_id] elif data["chatType"] == "chatGroup": chat_group = ChatGroup.query.filter_by(id=data["chatId"]).first() members = chat_group.get_members_with_only_id_entities() for member in members: if current_user.id == member.user_id: break else: # no break return msg = ChatGroupMsg(chat_group.id, current_user.id, data["content"]) db.session.add(msg) db.session.flush() db.session.add(ChatGroupMsgStatus(current_user.id, chat_group.id, msg.id, True)) receiver_user_ids = [] for member in members: if not member.user_id == current_user.id: db.session.add(ChatGroupMsgStatus(member.user_id, chat_group.id, msg.id, False)) receiver_user_ids.append(member.user_id) db.session.commit() msg_data_to_emit = {"id": msg.id, "type": "msg", "chatGroupId": chat_group.id, "goToChatUrl": f"/chat", "picUrl": current_user.small_avatar_url, "goToUrl": f"/{current_user.name}", "fromId": msg.from_id, "fromName": current_user.name, "content": msg.content, "datetime": f"{msg.datetime}+00:00"} elif data["chatType"] == "projectChatGroup": chat_group = ProjectChatGroup.query.filter_by(id=data["chatId"]).first() members = chat_group.get_members_with_only_id_entities() for member in members: if current_user.id == member.user_id: break else: # no break return msg = ProjectChatGroupMsg(chat_group.id, current_user.id, data["content"]) db.session.add(msg) db.session.flush() db.session.add(ProjectChatGroupMsgStatus(current_user.id, chat_group.id, msg.id, True)) receiver_user_ids = [] for member in members: if not member.user_id == current_user.id: db.session.add(ProjectChatGroupMsgStatus(member.user_id, chat_group.id, msg.id, False)) receiver_user_ids.append(member.user_id) db.session.commit() msg_data_to_emit = {"id": msg.id, "type": "msg", "projectChatGroupId": chat_group.id, "goToChatUrl": f"/chat", "picUrl": current_user.small_avatar_url, "goToUrl": f"/{current_user.name}", "fromId": msg.from_id, "fromName": current_user.name, "content": msg.content, "datetime": f"{msg.datetime}+00:00"} else: return emit("successfully_sent_msg", msg_data_to_emit, room=current_user.id) for id_ in receiver_user_ids: emit("receive_msg", msg_data_to_emit, room=id_)
def user_profile(username): user = User.get_by_name(username) if not user: abort(404) if not user.sign_up_complete: abort(404) # -- POST if request.method == "POST": form = request.form if form["submit"] == "editProfile": if current_user.name != username: abort(404) if form["token"] != user.token: return make_response(Response(""), 419) try: # change profile pic pic = PIL.Image.open(request.files["newProfilePic"].stream) small_pic = pic.copy() pic.thumbnail((280, 280)) small_pic.thumbnail((50, 50)) pic_fileobj = io.BytesIO() pic.save(pic_fileobj, format="png") pic_fileobj.seek(0) small_pic_fileobj = io.BytesIO() small_pic.save(small_pic_fileobj, format="png") small_pic_fileobj.seek(0) key = uuid4().hex + ".png" small_pic_key = uuid4().hex + ".png" s3_cli.upload_fileobj(pic_fileobj, app.config["S3_BUCKET_NAME"], key, ExtraArgs={ 'ACL': 'public-read', 'CacheControl': 'max-age: 86400', "ContentType": "image/png" }) s3_cli.upload_fileobj(small_pic_fileobj, app.config["S3_BUCKET_NAME"], small_pic_key, ExtraArgs={ 'ACL': 'public-read', 'CacheControl': 'max-age: 86400', "ContentType": "image/png" }) # delete prev avatar if not default avatar prev_bucket, prev_key = split_s3_obj_url(user.avatar_url) small_pic_prev_bucket, small_pic_prev_key = split_s3_obj_url( user.small_avatar_url) if prev_bucket == app.config[ "S3_BUCKET_NAME"]: # => not default avatar s3_cli.delete_object(Bucket=prev_bucket, Key=prev_key) s3_cli.delete_object(Bucket=small_pic_prev_bucket, Key=small_pic_prev_key) user.avatar_url = app.config["S3_BUCKET_URL"] + "/" + key user.small_avatar_url = app.config[ "S3_BUCKET_URL"] + "/" + small_pic_key except BadRequestKeyError: pass # change profile desc if len(form["newProfileDesc"]) <= 256: user.profile_desc = form["newProfileDesc"] db.session.commit() return make_response(Response(""), 200) elif form["submit"] == "removeFriend": f1 = Friendship.query.filter_by(user_id=current_user.id, friend_id=user.id).first() f2 = Friendship.query.filter_by(user_id=user.id, friend_id=current_user.id).first() if f1 and f2: db.session.delete(f1) db.session.delete(f2) db.session.commit() socketio.emit("friend_removed", {"id": current_user.id}, room=user.id, namespace="/") return make_response(Response(""), 200) abort(400) # -- GET if current_user.name == username or not user.private or current_user.is_friend_with( user.id): return redirect(f"/{username}/projects") abort(404)
def on_add_friend_to_project(data): if data["projectId"] in rooms() and current_user.is_project_owner_of( data["projectId"]): project = Project.query.filter_by(id=data["projectId"]).first() friend = User.get_by_name_or_email(data["friendNameOrEmail"]) if not friend or not current_user.is_friend_with(friend.id) \ or friend.is_project_collaborator_of(project.id): emit("add_friend_to_project_error_invalid_target", room=request.sid) return if data["role"] != "admin" and data["role"] != "access-only": return db.session.add( ProjectCollaboratorLink(data["projectId"], friend.id, data["role"])) project_chat_group = project.chat_group.first() if project_chat_group: member_data = { friend.id: { "id": friend.id, "role": "default", "name": friend.name, "picUrl": friend.small_avatar_url, "goToUrl": f"/{friend.name}" } } for member_user in db.session.query(ProjectChatGroupMemberLink) \ .filter_by(project_chat_group_id=project_chat_group.id) \ .join(User, User.id == ProjectChatGroupMemberLink.user_id) \ .with_entities(User.id, User.name, User.small_avatar_url): member_data[member_user.id] = { "id": member_user.id, "name": member_user.name, "picUrl": member_user.small_avatar_url, "goToUrl": f"/{member_user.name}", "role": "default" } emit("new_chat_group_member", { "chatGroupId": project_chat_group.id, "chatGroupType": "projectChatGroup", "member": { "id": friend.id, "name": friend.name, "picUrl": friend.small_avatar_url, "goToUrl": f"/{friend.name}", "role": "default" } }, namespace="/", room=member_user.id) db.session.add( ProjectChatGroupMemberLink(project_chat_group.id, friend.id, "default")) last_msg = current_user.get_last_msg(project_chat_group.id, "projectChatGroup") last_msg = { "content": last_msg.content, "datetime": f"{last_msg.datetime}+00:00" } if last_msg else "None" emit("new_chat_group", { "id": project_chat_group.id, "type": "projectChatGroup", "name": project_chat_group.name, "unreadCount": 0, "lastMsg": last_msg, "picUrl": "/static/img/group.png", "roleOfCurrentUser": "******", "members": member_data }, room=friend.id, namespace="/") db.session.commit() emit("successfully_added_friend_to_project", room=request.sid) emit("new_project_collab", { "id": friend.id, "name": friend.name, "picUrl": friend.small_avatar_url, "goToUrl": f"/{friend.name}", "role": data["role"] }, room=data["projectId"]) emit("now_collab_of_project", { "id": data["projectId"], "name": project.name, "ownerName": project.owner_name, "goToUrl": f"/{project.owner_name}/{project.name}" }, namespace="/", room=friend.id)
def project_page(project_owner_name, project_name): project = db.session.query(Project).filter_by( owner_name=project_owner_name, name=project_name).first() if not project: abort(404) owner_user = project.owner_user current_user_role = "owner" if owner_user.id == current_user.id else "no-role" project_data = { "id": project.id, "name": project.name, "ownerName": project.owner_name, "projectDesc": project.project_desc, "visibility": project.visibility, "chatGroupStatus": "activated" if ProjectChatGroup.query.filter_by( project_id=project.id).scalar() else "deactivated", "members": { owner_user.id: { "id": owner_user.id, "name": owner_user.name, "picUrl": owner_user.small_avatar_url, "goToUrl": f"/{owner_user.name}", "role": "owner" } }, "lists": {} } for member_user in ProjectCollaboratorLink.query.filter_by(project_id=project.id)\ .join(User)\ .with_entities(User.id, User.name, User.small_avatar_url, ProjectCollaboratorLink.user_role): project_data["members"][member_user.id] = { "id": member_user.id, "name": member_user.name, "picUrl": member_user.small_avatar_url, "goToUrl": f"/{member_user.name}", "role": member_user.user_role } if current_user.id == member_user.id: current_user_role = member_user.user_role for list_ in project.lists: project_data["lists"][list_.id] = { "name": list_.name, "listDesc": list_.list_desc, "pos": list_.pos, "attachedFiles": {}, "cards": {} } for file in list_.attached_files: project_data["lists"][list_.id]["attachedFiles"][ file.name] = file.url for card in list_.cards: card_members = {} for card_assignment in db.session.query( CardUserAssignment.user_id).filter_by(card_id=card.id): card_members[card_assignment.user_id] = 1 project_data["lists"][list_.id]["cards"][card.id] = { "name": card.name, "cardDesc": card.card_desc, "pos": card.pos, "listId": card.list_id, "attachedFiles": {}, "members": card_members } for file in card.attached_files: project_data["lists"][list_.id]["cards"][ card.id]["attachedFiles"][file.name] = file.url if current_user.name == project.owner_name: return render_template( "project.html.j2", invalid_names=invalid_names(), project_name=project.name, project_desc=project.project_desc, project=project_data, invite_link=f"https://taskstack.org/invite/{project.invite_code}", invite_as_admin_link= f"https://taskstack.org/invite/{project.invite_as_admin_code}", current_user_role=current_user_role) elif current_user.is_project_collaborator_of(project.id): return render_template("project.html.j2", project_name=project.name, project_desc=project.project_desc, project=project_data, current_user_role=current_user_role) else: if project.visibility == "public" \ or (project.visibility == "friends" and current_user.is_friend_with(owner_user.id)): return render_template("project.html.j2", project_name=project.name, project_desc=project.project_desc, project=project_data, current_user_role=current_user_role) abort(404)
def chat(): if not current_user.is_authenticated(): abort(404) chats = {"userToUser": {}, "chatGroup": {}, "projectChatGroup": {}} for friend in current_user.get_friends(): last_msg = current_user.get_last_msg(friend.id, "userToUser") last_msg = { "content": last_msg.content, "datetime": f"{last_msg.datetime}+00:00" } if last_msg else "None" chats["userToUser"][friend.id] = { "id": friend.id, "type": "userToUser", "name": friend.name, "unreadCount": current_user.get_unread_count_in_chat(friend.id, "userToUser"), "lastMsg": last_msg, "picUrl": friend.small_avatar_url, "goToUrl": f"/{friend.name}" } for chat_group in current_user.get_chat_groups_where_member(): last_msg = current_user.get_last_msg(chat_group.id, "chatGroup") last_msg = { "content": last_msg.content, "datetime": f"{last_msg.datetime}+00:00" } if last_msg else "None" members = {} for member_user in db.session.query(ChatGroupMemberLink) \ .filter_by(chat_group_id=chat_group.id) \ .join(User, User.id == ChatGroupMemberLink.user_id) \ .with_entities(User.id, User.name, User.small_avatar_url, ChatGroupMemberLink.user_role): members[member_user.id] = { "id": member_user.id, "name": member_user.name, "picUrl": member_user.small_avatar_url, "goToUrl": f"/{member_user.name}", "role": member_user.user_role } chats["chatGroup"][chat_group.id] = { "id": chat_group.id, "type": "chatGroup", "name": chat_group.name, "unreadCount": current_user.get_unread_count_in_chat(chat_group.id, "chatGroup"), "lastMsg": last_msg, "picUrl": "/static/img/group.png", "roleOfCurrentUser": chat_group.user_role, "members": members } for project_chat_group in current_user.get_project_chat_groups_where_member( ): last_msg = current_user.get_last_msg(project_chat_group.id, "projectChatGroup") last_msg = { "content": last_msg.content, "datetime": f"{last_msg.datetime}+00:00" } if last_msg else "None" members = {} for member_user in db.session.query(ProjectChatGroupMemberLink) \ .filter_by(project_chat_group_id=project_chat_group.id) \ .join(User, User.id == ProjectChatGroupMemberLink.user_id) \ .with_entities(User.id, User.name, User.small_avatar_url): members[member_user.id] = { "id": member_user.id, "name": member_user.name, "picUrl": member_user.small_avatar_url, "goToUrl": f"/{member_user.name}", "role": "default" } chats["projectChatGroup"][project_chat_group.id] = { "id": project_chat_group.id, "type": "projectChatGroup", "name": project_chat_group.name, "unreadCount": current_user.get_unread_count_in_chat(project_chat_group.id, "projectChatGroup"), "lastMsg": last_msg, "picUrl": "/static/img/group.png", "roleOfCurrentUser": project_chat_group.user_role, "members": members } user_to_chat_with_name = request.args.get("with") if user_to_chat_with_name: member_user = User.get_by_name(user_to_chat_with_name) if member_user: if current_user.is_friend_with(member_user.id): return render_template( "chat.html.j2", chats=chats, chat_to_open={ "id": User.get_by_name(user_to_chat_with_name).id, "type": "userToUser" }) return render_template("chat.html.j2", chats=chats)