Skip to content
Snippets Groups Projects
Commit 09a65421 authored by Jennifer Lindgren's avatar Jennifer Lindgren
Browse files

Backend: Create and update project files locally when someone is viewing a...

Backend: Create and update project files locally when someone is viewing a project to allow for faster syntax validation.
parent a1265fcb
Branches
No related tags found
No related merge requests found
print('hello world!')
\ No newline at end of file
""" Doc string """
print('Hello world!')
for i in range(0, 1):
print('Hello world!')
print('Hello!')
print('Hello!')
for i in range(0, 1):
test_var = '10'
TST = 2
import os
from __init__ import app
import json
from datetime import datetime
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow, fields
basedir = os.path.abspath(os.path.dirname(__file__))
# Database
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'db.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
ma = Marshmallow(app)
# EditorSettings
class EditorSettings(db.Model):
id = db.Column(db.Integer, primary_key=True)
fontSize = db.Column(db.Integer, nullable=False)
margin = db.Column(db.Integer, nullable=False)
tabSize = db.Column(db.Integer, nullable=False)
def __init__(self, font_size, margin, tab_size):
self.fontSize = font_size
self.margin = margin
self.tabSize = tab_size
class EditorSettingsSchema(ma.Schema):
class Meta:
model = EditorSettings
fields = ('id', 'fontSize', 'margin', 'tabSize')
editor_settings_schema = EditorSettingsSchema(strict=True)
# User
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(100), unique=True, nullable=False)
username = db.Column(db.String(50), unique=True, nullable=False)
password = db.Column(db.Text, nullable=False)
editorSettingsId = db.Column(db.Integer, db.ForeignKey(EditorSettings.id))
editorSettings = db.relationship("EditorSettings")
def __init__(self, email, username, password):
self.email = email
self.username = username
self.password = password
class UserSchema(ma.Schema):
editorSettings = ma.Nested(EditorSettingsSchema)
class Meta:
model = User
fields = ('id', 'email', 'username', 'editorSettingsId', 'editorSettings')
user_schema = UserSchema(strict=True)
users_schema = UserSchema(many=True, strict=True)
# Project
class Project(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(50), nullable=False)
creatorId = db.Column(db.Integer, db.ForeignKey(User.id), nullable=False)
creator = db.relationship('User')
created = db.Column(db.String(50), default=datetime.now, nullable=False)
edited = db.Column(db.String(50), onupdate=datetime.now)
archived = db.Column(db.Boolean, default=False, nullable=False)
def __init__(self, title, creator_id, created=None, edited=None, archived=False):
self.title = title
self.creatorId = creator_id
self.created = created
self.edited = edited
self.archived = archived
class ProjectSchema(ma.Schema):
creator = ma.Nested(UserSchema)
class Meta:
model = Project
fields = ('id', 'title', 'creatorId', 'creator', 'created', 'edited', 'archived')
project_schema = ProjectSchema(strict=True)
projects_schema = ProjectSchema(many=True, strict=True)
# File
class File(db.Model):
id = db.Column(db.Integer, primary_key=True)
projectId = db.Column(db.Integer, db.ForeignKey(Project.id), nullable=False)
project = db.relationship('Project', lazy='subquery')
name = db.Column(db.String(100), nullable=False)
isFolder = db.Column(db.Boolean, nullable=False)
parent = db.Column(db.String(100))
content = db.Column(db.Text)
def __init__(self, project_id, name, is_folder, parent, content):
self.projectId = project_id
self.name = name
self.isFolder = is_folder
self.parent = parent
self.content = content
class FileSchema(ma.Schema):
project = ma.Nested(ProjectSchema)
class Meta:
model = File
fields = ('id', 'projectId', 'project', 'name', 'isFolder', 'parent', 'content')
file_schema = FileSchema(strict=True)
files_schema = FileSchema(many=True, strict=True)
# Collaborator
class Collaborator(db.Model):
id = db.Column(db.Integer, primary_key=True)
projectId = db.Column(db.Integer, db.ForeignKey(Project.id), nullable=False)
project = db.relationship('Project', lazy='subquery')
userId = db.Column(db.Integer, db.ForeignKey(User.id), nullable=False)
user = db.relationship('User', lazy='subquery')
permission = db.Column(db.Text, nullable=False)
def __init__(self, project_id, user_id, permission):
self.projectId = project_id
self.userId = user_id
self.permission = permission
class CollaboratorSchema(ma.Schema):
project = ma.Nested(ProjectSchema)
user = ma.Nested(UserSchema)
class Meta:
fields = ('id', 'projectId', 'project', 'userId', 'user', 'permission')
collaborator_schema = CollaboratorSchema(strict=True)
collaborators_schema = CollaboratorSchema(many=True, strict=True)
# Message
class Message(db.Model):
id = db.Column(db.Integer, primary_key=True)
projectId = db.Column(db.Integer, db.ForeignKey(Project.id), nullable=False)
project = db.relationship('Project')
authorId = db.Column(db.Integer, db.ForeignKey(User.id), nullable=False)
author = db.relationship('User')
message = db.Column(db.Text)
time = db.Column(db.String(50), default=datetime.now, nullable=False)
def __init__(self, project_id, author_id, message, time=None):
self.projectId = project_id
self.authorId = author_id
self.message = message
self.time = time
class MessageSchema(ma.Schema):
project = ma.Nested(ProjectSchema)
author = ma.Nested(UserSchema)
class Meta:
fields = ('id', 'projectId', 'project', 'authorId', 'author', 'message', 'time')
message_schema = MessageSchema(strict=True)
messages_schema = MessageSchema(many=True, strict=True)
### USER ###
def add_user(new_user):
db.session.add(new_user)
db.session.commit()
def get_users():
all_users = User.query.all()
result = users_schema.dump(all_users)
return result.data
def get_user(id):
user = User.query.get(id)
return user
def update_user(id, updated_user):
user = User.query.get(id)
user.email = updated_user.email
user.username = updated_user.username
user.password = updated_user.password
user.editorSettingsId = updated_user.editorSettingsId
db.session.commit()
return user
def delete_user(id):
user = User.query.get(id)
db.session.delete(user)
db.session.commit()
return user
def delete_all_users():
num_users_deleted = db.session.query(User).delete()
db.session.commit()
return num_users_deleted
def is_user(user):
return user != None and 'id' in user.keys() and bool(User.query.get(user['id']))
def is_user_id(userId):
return userId != None and bool(User.query.get(userId))
def is_unregistered_email(email):
return not bool(get_user_from_email(email))
def is_unregistered_username(username):
return not bool(get_user_from_username(username))
def get_user_from_email(email):
return User.query.filter_by(email=email).first()
def get_user_from_username(username):
return User.query.filter_by(username=username).first()
def get_username_from_email(email):
return get_user_from_email(email).username
def is_valid_email_password(email, password):
user = get_user_from_email(email)
valid_password = user.password if user else None
return password != None and password == valid_password
def is_valid_username_password(username, password):
user = get_user_from_username(username)
valid_password = user.password if user else None
return password != None and password == valid_password
def change_password(username, newPassword):
user = get_user_from_username(username)
user.password = newPassword
db.session.commit()
return user
### EDITORSETTINGS ###
def add_editor_settings(editor_settings):
db.session.add(editor_settings)
db.session.commit()
def get_editor_settings(user_id):
return EditorSettings.query.filter_by(userId=user_id).first()
def update_editor_settings(updated_editor_settings):
editor_settings = EditorSettings.query.get(updated_editor_settings.id)
editor_settings.fontSize = updated_editor_settings.fontSize
editor_settings.margin = updated_editor_settings.margin
editor_settings.tabSize = updated_editor_settings.tabSize
db.session.commit()
return editor_settings
def delete_editor_settings(id):
editor_settings = EditorSettings.query.get(id)
db.session.delete(editor_settings)
db.session.commit()
return editor_settings
def delete_all_editor_settings():
num_editor_settings_deleted = db.session.query(EditorSettings).delete()
db.session.commit()
return num_editor_settings_deleted
### PROJECT ###
def add_project(project):
db.session.add(project)
db.session.commit()
def get_projects():
all_projects = Project.query.all()
result = projects_schema.dump(all_projects)
return result.data
def get_user_projects(user_id):
""" Returns all projects where user is the creator or a collaborator """
user_projects = Project.query.filter_by(creatorId=user_id).all()
collaborator_project_ids = [id for id, in db.session.query(Collaborator.projectId).filter_by(userId=user_id)]
user_projects += Project.query.filter(Project.id.in_(collaborator_project_ids)).all()
result = projects_schema.dump(user_projects)
return result.data
def get_project(id):
project = Project.query.get(id)
return project
def update_project(updated_project):
project = Project.query.get(updated_project.id)
project.title = updated_project.title
project.creatorId = updated_project.creatorId
project.archived = updated_project.archived
db.session.commit()
return project
def delete_project(id):
project = Project.query.get(id)
db.session.delete(project)
db.session.commit()
return project
def delete_user_projects(user_id):
""" Deletes all projects owned by user with id. """
user = User.query.get(user_id)
user_projects_query = Project.query.filter_by(creatorId=user_id)
user_projects = user_projects_query.all()
for project in user_projects:
delete_project_files(project.id)
delete_project_collaborators(project.id)
delete_project_messages(project.id)
delete_project(project.id)
num_projects_deleted = user_projects_query.delete()
db.session.commit()
return num_projects_deleted
def delete_all_projects():
num_projects_deleted = db.session.query(Project).delete()
db.session.commit()
return num_projects_deleted
### FILE ###
def add_file(file):
db.session.add(file)
db.session.commit()
def get_file(id):
return File.query.get(id)
def get_files():
all_files = File.query.all()
result = files_schema.dump(all_files)
return result.data
def get_project_files(project_id):
project_files = File.query.filter_by(projectId=project_id).all()
result = files_schema.dump(project_files)
return result.data
def update_file(updated_file):
file = File.query.get(updated_file.id)
file.projectId = updated_file.projectId
file.name = updated_file.name
file.isFolder = updated_file.isFolder
file.parent = updated_file.parent
file.content = updated_file.content
db.session.commit()
return file
def delete_file(file_id):
file = File.query.filter_by(id=file_id).first()
db.session.delete(file)
db.session.commit()
return file
def delete_project_files(project_id):
num_project_files_deleted = File.query.filter_by(projectId=project_id).delete()
db.session.commit()
return num_project_files_deleted
def delete_all_files():
num_files_deleted = db.session.query(File).delete()
db.session.commit()
return num_files_deleted
### COLLABORATOR ###
def add_collaborator(collaborator):
db.session.add(collaborator)
db.session.commit()
def get_collaborator(id):
collaborator = Collaborator.query.get(id)
return collaborator
def get_collaborators():
all_collaborators = Collaborator.query.all()
result = collaborators_schema.dump(all_collaborators)
return result.data
def get_project_collaborators(project_id):
project_collaborators = Collaborator.query.filter_by(projectId=project_id).all()
result = collaborators_schema.dump(project_collaborators)
return result.data
def update_collaborator(updated_collaborator):
collaborator = Collaborator.query.get(updated_collaborator.id)
collaborator.projectId = updated_collaborator.projectId
collaborator.userId = updated_collaborator.userId
collaborator.permission = updated_collaborator.permission
db.session.commit()
return collaborator
def delete_collaborator(collaborator_id):
collaborator = Collaborator.query.filter_by(id=collaborator_id).first()
db.session.delete(collaborator)
db.session.commit()
return collaborator
def delete_project_collaborators(project_id):
num_project_collaborators_deleted = Collaborator.query.filter_by(projectId=project_id).delete()
db.session.commit()
return num_project_collaborators_deleted
def delete_all_collaborators():
num_collaborators_deleted = db.session.query(Collaborator).delete()
db.session.commit()
return num_collaborators_deleted
### Message ###
def add_message(message):
db.session.add(message)
db.session.commit()
def get_message(id):
message = Message.query.get(id)
return message
def get_messages():
all_messages = Message.query.all()
result = messages_schema.dump(all_messages)
return result.data
def get_project_messages(project_id):
project_messages = Message.query.filter_by(projectId=project_id).all()
result = messages_schema.dump(project_messages)
return result.data
def update_message(updated_message):
message = Message.query.get(updated_message.id)
message.projectId = updated_message.projectId
message.autorId = updated_message.autorId
message.time = updated_message.time
db.session.commit()
return message
def delete_project_messages(project_id):
num_project_messages_deleted = Message.query.filter_by(projectId=project_id).delete()
db.session.commit()
return num_project_messages_deleted
def delete_all_messages():
num_messages_deleted = db.session.query(Message).delete()
db.session.commit()
return num_messages_deleted
print('Hello world!')
\ No newline at end of file
print('Hello!')
\ No newline at end of file
This diff is collapsed.
import os
from __init__ import app
import json
from datetime import datetime
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow, fields
basedir = os.path.abspath(os.path.dirname(__file__))
# Database
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'db.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
ma = Marshmallow(app)
# EditorSettings
class EditorSettings(db.Model):
id = db.Column(db.Integer, primary_key=True)
fontSize = db.Column(db.Integer, nullable=False)
margin = db.Column(db.Integer, nullable=False)
tabSize = db.Column(db.Integer, nullable=False)
def __init__(self, font_size, margin, tab_size):
self.fontSize = font_size
self.margin = margin
self.tabSize = tab_size
class EditorSettingsSchema(ma.Schema):
class Meta:
model = EditorSettings
fields = ('id', 'fontSize', 'margin', 'tabSize')
editor_settings_schema = EditorSettingsSchema(strict=True)
# User
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(100), unique=True, nullable=False)
username = db.Column(db.String(50), unique=True, nullable=False)
password = db.Column(db.Text, nullable=False)
editorSettingsId = db.Column(db.Integer, db.ForeignKey(EditorSettings.id))
editorSettings = db.relationship("EditorSettings")
def __init__(self, email, username, password):
self.email = email
self.username = username
self.password = password
class UserSchema(ma.Schema):
editorSettings = ma.Nested(EditorSettingsSchema)
class Meta:
model = User
fields = ('id', 'email', 'username', 'editorSettingsId', 'editorSettings')
user_schema = UserSchema(strict=True)
users_schema = UserSchema(many=True, strict=True)
# Project
class Project(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(50), nullable=False)
creatorId = db.Column(db.Integer, db.ForeignKey(User.id), nullable=False)
creator = db.relationship('User')
created = db.Column(db.String(50), default=datetime.now, nullable=False)
edited = db.Column(db.String(50), onupdate=datetime.now)
archived = db.Column(db.Boolean, default=False, nullable=False)
def __init__(self, title, creator_id, created=None, edited=None, archived=False):
self.title = title
self.creatorId = creator_id
self.created = created
self.edited = edited
self.archived = archived
class ProjectSchema(ma.Schema):
creator = ma.Nested(UserSchema)
class Meta:
model = Project
fields = ('id', 'title', 'creatorId', 'creator', 'created', 'edited', 'archived')
project_schema = ProjectSchema(strict=True)
projects_schema = ProjectSchema(many=True, strict=True)
# File
class File(db.Model):
id = db.Column(db.Integer, primary_key=True)
projectId = db.Column(db.Integer, db.ForeignKey(Project.id), nullable=False)
project = db.relationship('Project', lazy='subquery')
name = db.Column(db.String(100), nullable=False)
isFolder = db.Column(db.Boolean, nullable=False)
parent = db.Column(db.String(100))
content = db.Column(db.Text)
def __init__(self, project_id, name, is_folder, parent, content):
self.projectId = project_id
self.name = name
self.isFolder = is_folder
self.parent = parent
self.content = content
class FileSchema(ma.Schema):
project = ma.Nested(ProjectSchema)
class Meta:
model = File
fields = ('id', 'projectId', 'project', 'name', 'isFolder', 'parent', 'content')
file_schema = FileSchema(strict=True)
files_schema = FileSchema(many=True, strict=True)
# Collaborator
class Collaborator(db.Model):
id = db.Column(db.Integer, primary_key=True)
projectId = db.Column(db.Integer, db.ForeignKey(Project.id), nullable=False)
project = db.relationship('Project', lazy='subquery')
userId = db.Column(db.Integer, db.ForeignKey(User.id), nullable=False)
user = db.relationship('User', lazy='subquery')
permission = db.Column(db.Text, nullable=False)
def __init__(self, project_id, user_id, permission):
self.projectId = project_id
self.userId = user_id
self.permission = permission
class CollaboratorSchema(ma.Schema):
project = ma.Nested(ProjectSchema)
user = ma.Nested(UserSchema)
class Meta:
fields = ('id', 'projectId', 'project', 'userId', 'user', 'permission')
collaborator_schema = CollaboratorSchema(strict=True)
collaborators_schema = CollaboratorSchema(many=True, strict=True)
# Message
class Message(db.Model):
id = db.Column(db.Integer, primary_key=True)
projectId = db.Column(db.Integer, db.ForeignKey(Project.id), nullable=False)
project = db.relationship('Project')
authorId = db.Column(db.Integer, db.ForeignKey(User.id), nullable=False)
author = db.relationship('User')
message = db.Column(db.Text)
time = db.Column(db.String(50), default=datetime.now, nullable=False)
def __init__(self, project_id, author_id, message, time=None):
self.projectId = project_id
self.authorId = author_id
self.message = message
self.time = time
class MessageSchema(ma.Schema):
project = ma.Nested(ProjectSchema)
author = ma.Nested(UserSchema)
class Meta:
fields = ('id', 'projectId', 'project', 'authorId', 'author', 'message', 'time')
message_schema = MessageSchema(strict=True)
messages_schema = MessageSchema(many=True, strict=True)
### USER ###
def add_user(new_user):
db.session.add(new_user)
db.session.commit()
def get_users():
all_users = User.query.all()
result = users_schema.dump(all_users)
return result.data
def get_user(id):
user = User.query.get(id)
return user
def update_user(id, updated_user):
user = User.query.get(id)
user.email = updated_user.email
user.username = updated_user.username
user.password = updated_user.password
user.editorSettingsId = updated_user.editorSettingsId
db.session.commit()
return user
def delete_user(id):
user = User.query.get(id)
db.session.delete(user)
db.session.commit()
return user
def delete_all_users():
num_users_deleted = db.session.query(User).delete()
db.session.commit()
return num_users_deleted
def is_user(user):
return user != None and 'id' in user.keys() and bool(User.query.get(user['id']))
def is_user_id(userId):
return userId != None and bool(User.query.get(userId))
def is_unregistered_email(email):
return not bool(get_user_from_email(email))
def is_unregistered_username(username):
return not bool(get_user_from_username(username))
def get_user_from_email(email):
return User.query.filter_by(email=email).first()
def get_user_from_username(username):
return User.query.filter_by(username=username).first()
def get_username_from_email(email):
return get_user_from_email(email).username
def is_valid_email_password(email, password):
user = get_user_from_email(email)
valid_password = user.password if user else None
return password != None and password == valid_password
def is_valid_username_password(username, password):
user = get_user_from_username(username)
valid_password = user.password if user else None
return password != None and password == valid_password
def change_password(username, newPassword):
user = get_user_from_username(username)
user.password = newPassword
db.session.commit()
return user
### EDITORSETTINGS ###
def add_editor_settings(editor_settings):
db.session.add(editor_settings)
db.session.commit()
def get_editor_settings(user_id):
return EditorSettings.query.filter_by(userId=user_id).first()
def update_editor_settings(updated_editor_settings):
editor_settings = EditorSettings.query.get(updated_editor_settings.id)
editor_settings.fontSize = updated_editor_settings.fontSize
editor_settings.margin = updated_editor_settings.margin
editor_settings.tabSize = updated_editor_settings.tabSize
db.session.commit()
return editor_settings
def delete_editor_settings(id):
editor_settings = EditorSettings.query.get(id)
db.session.delete(editor_settings)
db.session.commit()
return editor_settings
def delete_all_editor_settings():
num_editor_settings_deleted = db.session.query(EditorSettings).delete()
db.session.commit()
return num_editor_settings_deleted
### PROJECT ###
def add_project(project):
db.session.add(project)
db.session.commit()
def get_projects():
all_projects = Project.query.all()
result = projects_schema.dump(all_projects)
return result.data
def get_user_projects(user_id):
""" Returns all projects where user is the creator or a collaborator """
user_projects = Project.query.filter_by(creatorId=user_id).all()
collaborator_project_ids = [id for id, in db.session.query(Collaborator.projectId).filter_by(userId=user_id)]
user_projects += Project.query.filter(Project.id.in_(collaborator_project_ids)).all()
result = projects_schema.dump(user_projects)
return result.data
def get_project(id):
project = Project.query.get(id)
return project
def update_project(updated_project):
project = Project.query.get(updated_project.id)
project.title = updated_project.title
project.creatorId = updated_project.creatorId
project.archived = updated_project.archived
db.session.commit()
return project
def delete_project(id):
project = Project.query.get(id)
db.session.delete(project)
db.session.commit()
return project
def delete_user_projects(user_id):
""" Deletes all projects owned by user with id. """
user = User.query.get(user_id)
user_projects_query = Project.query.filter_by(creatorId=user_id)
user_projects = user_projects_query.all()
for project in user_projects:
delete_project_files(project.id)
delete_project_collaborators(project.id)
delete_project_messages(project.id)
delete_project(project.id)
num_projects_deleted = user_projects_query.delete()
db.session.commit()
return num_projects_deleted
def delete_all_projects():
num_projects_deleted = db.session.query(Project).delete()
db.session.commit()
return num_projects_deleted
### FILE ###
def add_file(file):
db.session.add(file)
db.session.commit()
def get_file(id):
return File.query.get(id)
def get_files():
all_files = File.query.all()
result = files_schema.dump(all_files)
return result.data
def get_project_files(project_id):
project_files = File.query.filter_by(projectId=project_id).all()
result = files_schema.dump(project_files)
return result.data
def update_file(updated_file):
file = File.query.get(updated_file.id)
file.projectId = updated_file.projectId
file.name = updated_file.name
file.isFolder = updated_file.isFolder
file.parent = updated_file.parent
file.content = updated_file.content
db.session.commit()
return file
def delete_file(file_id):
file = File.query.filter_by(id=file_id).first()
db.session.delete(file)
db.session.commit()
return file
def delete_project_files(project_id):
num_project_files_deleted = File.query.filter_by(projectId=project_id).delete()
db.session.commit()
return num_project_files_deleted
def delete_all_files():
num_files_deleted = db.session.query(File).delete()
db.session.commit()
return num_files_deleted
### COLLABORATOR ###
def add_collaborator(collaborator):
db.session.add(collaborator)
db.session.commit()
def get_collaborator(id):
collaborator = Collaborator.query.get(id)
return collaborator
def get_collaborators():
all_collaborators = Collaborator.query.all()
result = collaborators_schema.dump(all_collaborators)
return result.data
def get_project_collaborators(project_id):
project_collaborators = Collaborator.query.filter_by(projectId=project_id).all()
result = collaborators_schema.dump(project_collaborators)
return result.data
def update_collaborator(updated_collaborator):
collaborator = Collaborator.query.get(updated_collaborator.id)
collaborator.projectId = updated_collaborator.projectId
collaborator.userId = updated_collaborator.userId
collaborator.permission = updated_collaborator.permission
db.session.commit()
return collaborator
def delete_collaborator(collaborator_id):
collaborator = Collaborator.query.filter_by(id=collaborator_id).first()
db.session.delete(collaborator)
db.session.commit()
return collaborator
def delete_project_collaborators(project_id):
num_project_collaborators_deleted = Collaborator.query.filter_by(projectId=project_id).delete()
db.session.commit()
return num_project_collaborators_deleted
def delete_all_collaborators():
num_collaborators_deleted = db.session.query(Collaborator).delete()
db.session.commit()
return num_collaborators_deleted
### Message ###
def add_message(message):
db.session.add(message)
db.session.commit()
def get_message(id):
message = Message.query.get(id)
return message
def get_messages():
all_messages = Message.query.all()
result = messages_schema.dump(all_messages)
return result.data
def get_project_messages(project_id):
project_messages = Message.query.filter_by(projectId=project_id).all()
result = messages_schema.dump(project_messages)
return result.data
def update_message(updated_message):
message = Message.query.get(updated_message.id)
message.projectId = updated_message.projectId
message.autorId = updated_message.autorId
message.time = updated_message.time
db.session.commit()
return message
def delete_project_messages(project_id):
num_project_messages_deleted = Message.query.filter_by(projectId=project_id).delete()
db.session.commit()
return num_project_messages_deleted
def delete_all_messages():
num_messages_deleted = db.session.query(Message).delete()
db.session.commit()
return num_messages_deleted
\ No newline at end of file
import os, shutil
from flask import json
from flask_socketio import SocketIO, send, emit, join_room, leave_room
import diff_match_patch as dmp_module
from simpleflock import SimpleFlock
from __init__ import app
import database_helper as db
SIMPLE_FLOCK_TIMEOUT = 10
socketio = SocketIO(app)
dmp = dmp_module.diff_match_patch()
project_viewers = dict()
def has_viewer(username, project_id):
for viewer in project_viewers[str(project_id)]:
if viewer['username'] == username:
return True
return False
def set_viewer(viewer, project_id):
filtered_viewers = []
for curr_viewer in project_viewers[str(project_id)]:
if curr_viewer['username'] != viewer['username']:
filtered_viewers.append(curr_viewer)
project_viewers[str(project_id)].append(viewer)
project_viewers[str(project_id)] = filtered_viewers
def add_project_viewer(project_id, username):
viewer = {
'username': username,
'cursor': {
'fileId': None,
'position': None,
'added': False
}
}
if not str(project_id) in project_viewers.keys():
project_viewers[str(project_id)] = [viewer]
elif not has_viewer(username, project_id):
project_viewers[str(project_id)].append(viewer)
else:
set_viewer(viewer, project_id)
def remove_project_viewer(project_id, username):
if str(project_id) in project_viewers.keys() and \
has_viewer(username, project_id):
viewers = []
for viewer in project_viewers[str(project_id)]:
if viewer['username'] != username:
viewers.append(viewer)
project_viewers[str(project_id)] = viewers
## Join user room
@socketio.on('joinUserRoom')
def on_join_user_room(data):
data = json.loads(data)
user_id = data['userId']
room = 'user' + str(user_id)
join_room(room)
emit('joinUserRoom', {
'on': 'joinUserRoom',
'userId': user_id
}, room=room)
@socketio.on('leaveUserRoom')
def on_leave_user_room(data):
data = json.loads(data)
user_id = data['userId']
room = 'user' + str(user_id)
leave_room(room)
emit('leaveUserRoom', {
'on': 'leaveUserRoom',
'userId': user_id
}, room=room)
## Join project room
@socketio.on('joinProjectRoom')
def on_join_project_room(data):
data = json.loads(data)
username = data['username']
project_id = data['projectId']
room = 'project' + str(project_id)
join_room(room)
emit('joinProjectRoom', {
'on': 'joinProjectRoom',
'username': username,
'projectId' : project_id
}, room=room)
@socketio.on('leaveProjectRoom')
def on_leave_project_room(data):
data = json.loads(data)
username = data['username']
project_id = data['projectId']
room = 'project' + str(project_id)
leave_room(room)
emit('leaveProjectRoom', {
'on': 'leaveProjectRoom',
'username': username,
'projectId' : project_id
}, room=room)
## Project handling ##
@socketio.on('projectCreated')
def handle_project_created(data):
project = json.loads(data)
emit('projectCreated', {
'on': 'projectCreated',
'project': project
}, room = 'project' + str(project['id']))
@socketio.on('projectChanged')
def handle_project_changed(data):
project = json.loads(data)
emit('projectChanged', {
'on': 'projectChanged',
'project': project
}, room = 'project' + str(project['id']))
@socketio.on('projectDeleted')
def handle_project_deleted(data):
projectId = json.loads(data)
emit('projectDeleted', {
'on': 'projectDeleted',
'projectId': projectId
}, room = 'project' + str(projectId))
@socketio.on('collaboratorAdded')
def handle_collaborator_added(data):
collaborator = json.loads(data)
emit('collaboratorAdded', {
'on': 'collaboratorAdded',
'collaborator': collaborator
}, room = 'user' + str(collaborator['userId']))
@socketio.on('collaboratorChanged')
def handle_collaborator_changed(data):
collaborator = json.loads(data)
emit('collaboratorChanged', {
'on': 'collaboratorChanged',
'collaborator': collaborator
}, room = 'project' + str(collaborator['projectId']))
## Join open project room
@socketio.on('joinOpenProjectRoom')
def on_join_open_project_room(data):
data = json.loads(data)
username = data['username']
project_id = data['projectId']
room = 'openProject' + str(project_id)
join_room(room)
add_project_viewer(project_id, username)
if not os.path.exists(str(project_id)):
os.mkdir(str(project_id))
for file in db.get_project_files(project_id):
dir_name = str(project_id) + ('/' + file['parent'] if file['parent'] else '')
if not os.path.exists(dir_name):
os.makedirs(dir_name)
if not file['isFolder']:
f = open(dir_name + '/' + file['name'], "a+")
f.write(file['content'])
f.close()
emit('joinOpenProjectRoom', {
'on': 'joinOpenProjectRoom',
'username': username,
'viewers': project_viewers[str(project_id)]
}, room=room)
@socketio.on('leaveOpenProjectRoom')
def on_leave_open_project_room(data):
data = json.loads(data)
username = data['username']
project_id = data['projectId']
room = 'openProject' + str(project_id)
leave_room(room)
remove_project_viewer(project_id, username)
if not project_viewers[str(project_id)] and os.path.exists(str(project_id)):
shutil.rmtree(str(project_id))
emit('leaveOpenProjectRoom', {
'on': 'leaveOpenProjectRoom',
'username': username,
'viewers': project_viewers[str(project_id)]
}, room=room)
## File handling ##
@socketio.on('fileCreated')
def handle_file_created(data):
file = json.loads(data)
emit('fileCreated', {
'on': 'fileCreated',
'file': file
}, room = 'openProject' + str(file['projectId']))
@socketio.on('fileChanged')
def handle_file_changed(data):
file = json.loads(data)
emit('fileChanged', {
'on': 'fileChanged',
'file': file
}, room = 'openProject' + str(file['projectId']))
@socketio.on('fileContentChanged')
def handle_file_content_changed(data):
data = json.loads(data)
project_id = data['projectId']
file_id = data['fileId']
patches_text = data['patchesText']
patches = dmp.patch_fromText(patches_text)
file = db.get_file(file_id)
file.content = dmp.patch_apply(patches, file.content)[0]
db.update_file(file)
# Update file locally on server if project is open
open_project_path = str(file.projectId) + '/'
if os.path.exists(open_project_path):
if file.parent:
file_path = open_project_path + file.parent + '/' + file.name
else:
file_path = open_project_path + file.name
if os.path.exists(file_path):
with SimpleFlock(str(file.projectId) + 'lock', SIMPLE_FLOCK_TIMEOUT):
if os.path.exists(file_path):
f = open(file_path, 'w')
f.write(file.content)
f.close()
emit('fileContentChanged', {
'on': 'fileContentChanged',
'projectId': project_id,
'fileId': file_id,
'patchesText' : patches_text
}, room = 'openProject' + str(project_id), include_self=False)
@socketio.on('fileDeleted')
def handle_file_deleted(data):
file = json.loads(data)
emit('fileDeleted', {
'on': 'fileDeleted',
'file': file
}, room = 'openProject' + str(file['projectId']))
## Chat ##
@socketio.on('message')
def handle_message(data):
data = json.loads(data)
projectId = data['projectId']
username = data['username']
message = data['message']
author = db.get_user_from_username(username)
new_message = db.Message(
projectId,
author.id,
message
)
db.add_message(new_message)
emit('message', {
'on': 'message',
'author': db.user_schema.dumps(author),
'time': new_message.time,
'message': message
}, room = 'openProject' + str(projectId))
## Editor ##
@socketio.on('viewerCursorChanged')
def handle_viewer_cursor_changed(data):
data = json.loads(data)
project_id = data['projectId']
file_id = data['fileId']
username = data['username']
cursor_position = data['cursorPosition']
if not str(project_id) in project_viewers.keys() \
or not has_viewer(username, project_id):
add_project_viewer(project_id, username)
for viewer in project_viewers[str(project_id)]:
if viewer['username'] == username:
viewer['cursor'] = {
'fileId': file_id,
'position': cursor_position
}
emit('viewerCursorChanged', {
'on': 'viewerCursorChanged',
'viewer': username,
'fileId': file_id,
'cursorPosition': cursor_position
}, room = 'openProject' + str(project_id), include_self=False)
\ No newline at end of file
print('Hello world!')
\ No newline at end of file
...@@ -17,6 +17,7 @@ pyjwt = "*" ...@@ -17,6 +17,7 @@ pyjwt = "*"
bson = "*" bson = "*"
flask-socketio = "*" flask-socketio = "*"
diff-match-patch = "*" diff-match-patch = "*"
simpleflock = "*"
[requires] [requires]
python_version = "3.6" python_version = "3.6"
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "c40b8fdfa182b209d5d3d2e5c2cac67b40cbc77ff95f0ae845d722a57fae950b" "sha256": "0cbc6707a54e77c6ff91fec870c927dfba819c9aaa97d84191e5ebef71e9cfba"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
...@@ -96,11 +96,11 @@ ...@@ -96,11 +96,11 @@
}, },
"flask": { "flask": {
"hashes": [ "hashes": [
"sha256:2271c0070dbcb5275fad4a82e29f23ab92682dc45f9dfbc22c02ba9b9322ce48", "sha256:ad7c6d841e64296b962296c2c2dabc6543752985727af86a975072dea984b6f3",
"sha256:a080b744b7e345ccfcbc77954861cb05b3c63786e93f2b3875e0913d44b43f05" "sha256:e7d32475d1de5facaa55e3958bc4ec66d3762076b074296aa50ef8fdc5b9df61"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.0.2" "version": "==1.0.3"
}, },
"flask-bcrypt": { "flask-bcrypt": {
"hashes": [ "hashes": [
...@@ -134,11 +134,11 @@ ...@@ -134,11 +134,11 @@
}, },
"flask-socketio": { "flask-socketio": {
"hashes": [ "hashes": [
"sha256:8d8f9f104db5ddff1b06ba322d8e158881d590144199c993fe26cf53218c7edd", "sha256:841dc9636fcf0659223745434b7ceef56f716fede2311ec26cb97af30648ca22",
"sha256:f9b9c95c82b62381862fd3bc55cea7fcc08e787f6bb63fdc79a2f258df2bdc9a" "sha256:f44b2fc91149c1b2b522c8fd64824d10d4e38d535c2cb76623c22b1e9eeb9de9"
], ],
"index": "pypi", "index": "pypi",
"version": "==3.3.2" "version": "==4.0.0"
}, },
"flask-sqlalchemy": { "flask-sqlalchemy": {
"hashes": [ "hashes": [
...@@ -233,17 +233,24 @@ ...@@ -233,17 +233,24 @@
}, },
"python-engineio": { "python-engineio": {
"hashes": [ "hashes": [
"sha256:a89d2cff7f9b447d37c450c2666101d97043b4b22524bf4efaafcb9784c9f7f4", "sha256:06bd817c0ea50df62e0ea31b89f427ba4ef6f954e09cb0f9036bcfce8193e304",
"sha256:fd14357f0b854de729cc2dba960ceba1d20da973c91f289110807f0bb2f69935" "sha256:0886831a4ce9f0e8293b927c4b8e4a3dc6dba4a55830abb9c170b12b34d453e9"
], ],
"version": "==3.5.1" "version": "==3.6.0"
}, },
"python-socketio": { "python-socketio": {
"hashes": [ "hashes": [
"sha256:aa702157694d55a743fb6f1cc0bd1af58fbfda8a7d71d747d4b12d6dac29cab3", "sha256:80810f40a5b276937a95d4944229fa9c20ee61963365387549fd943589661a6f",
"sha256:cd225eb0bb3b348665727cfaafad1e455ee13b8fd9ea9ff2691082b88b9a9444" "sha256:c128d320b23ce3c4323ca5b0e20f602a075ceea56f368f6b9f52bed48d97df71"
], ],
"version": "==3.1.2" "version": "==4.0.3"
},
"simpleflock": {
"hashes": [
"sha256:0dfebcbe4ae574fdd01466be002dc8cd274ba350b90d11ef910c4bc9766c59eb"
],
"index": "pypi",
"version": "==0.0.3"
}, },
"six": { "six": {
"hashes": [ "hashes": [
......
...@@ -2,17 +2,20 @@ import os, sys, subprocess, shutil ...@@ -2,17 +2,20 @@ import os, sys, subprocess, shutil
import random import random
import logging import logging
from subprocess import Popen, PIPE
from datetime import datetime
from flask import Flask, request, jsonify, Response, json from flask import Flask, request, jsonify, Response, json
from flask_jwt_extended import JWTManager from flask_jwt_extended import JWTManager
from flask_jwt_extended import (create_access_token, create_refresh_token, from flask_jwt_extended import (create_access_token, create_refresh_token,
jwt_required, jwt_refresh_token_required, get_jwt_identity) jwt_required, jwt_refresh_token_required, get_jwt_identity)
from flask_bcrypt import Bcrypt from flask_bcrypt import Bcrypt
from flask_socketio import emit
from base64 import b64decode from base64 import b64decode
from datetime import datetime from simpleflock import SimpleFlock
from __init__ import app from __init__ import app
import database_helper as db import database_helper as db
from socketio_helper import socketio from socketio_helper import socketio, SIMPLE_FLOCK_TIMEOUT
flask_bcrypt = Bcrypt(app) flask_bcrypt = Bcrypt(app)
jwt = JWTManager(app) jwt = JWTManager(app)
...@@ -30,7 +33,8 @@ def generate_response(response, status, headers={}): ...@@ -30,7 +33,8 @@ def generate_response(response, status, headers={}):
response.status_code = status response.status_code = status
response.headers = {**{ response.headers = {**{
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Access-Control-Expose-Headers' : 'X-Auth-Token', 'Access-Control-Expose-Headers': 'X-Auth-Token',
'Access-Control-Allow-Origin': '*'
}, **headers} }, **headers}
return response return response
...@@ -265,7 +269,6 @@ def new_project(): ...@@ -265,7 +269,6 @@ def new_project():
else: else:
new_project = db.Project(title, creatorId) new_project = db.Project(title, creatorId)
db.add_project(new_project) db.add_project(new_project)
app.logger.error(new_project.id)
if collaborators: if collaborators:
for collaborator in collaborators: for collaborator in collaborators:
...@@ -389,27 +392,27 @@ def delete_project_request(project_id): ...@@ -389,27 +392,27 @@ def delete_project_request(project_id):
@jwt_required @jwt_required
def parse_file_request(project_id): def parse_file_request(project_id):
if db.get_project(project_id): if db.get_project(project_id):
os.mkdir(str(project_id)) if os.path.exists(str(project_id)):
for file in db.get_project_files(project_id): with SimpleFlock(str(project_id) + 'lock', SIMPLE_FLOCK_TIMEOUT):
dir_name = str(project_id) + ('/' + file['parent'] if file['parent'] else '') find_cmd = 'find ' + str(project_id) + '/ -type f -name "*.py"'
if not os.path.exists(dir_name): find = Popen(find_cmd, shell=True, stdout=PIPE)
os.makedirs(dir_name) files = find.communicate()[0].decode('utf-8')
if not file['isFolder']: files = ' '.join(files.splitlines())
f = open(dir_name + '/' + file['name'], "a+")
f.write(file['content']) pylint_cmd = 'pylint --output-format=json ' + files
f.close() pylint = Popen(pylint_cmd, shell=True, stdout=PIPE)
result = subprocess.run(['pylint', '--output-format=json', str(project_id) + '/'],\ result = pylint.communicate()[0].decode('utf-8')
stdout=subprocess.PIPE).stdout.decode('utf-8') else:
shutil.rmtree(str(project_id)) result = '[]'
return generate_response(jsonify({ return generate_response(jsonify({
'success': True, 'success': True,
'message': 'Successfully parsed file.', 'message': 'Successfully parsed files.',
'result': result 'result': result
}), OK_STATUS_CODE) }), OK_STATUS_CODE)
else: else:
return generate_response(jsonify({ return generate_response(jsonify({
'success': False, 'success': False,
'message': 'No such file' 'message': 'No such project'
}), BAD_REQUEST_STATUS_CODE) }), BAD_REQUEST_STATUS_CODE)
### FILE ### ### FILE ###
...@@ -431,14 +434,30 @@ def create_file_request(): ...@@ -431,14 +434,30 @@ def create_file_request():
project.edited = datetime.now() project.edited = datetime.now()
db.update_project(project) db.update_project(project)
# Add file locally on server if project is open
open_project_path = str(new_file.projectId) + '/'
if os.path.exists(open_project_path):
if new_file.parent:
file_path = open_project_path + new_file.parent + '/' + new_file.name
else:
file_path = open_project_path + new_file.name
if new_file.isFolder:
os.makedirs(file_path)
else:
f = open(file_path, 'w+')
f.write(new_file.content)
f.close()
return generate_response(db.file_schema.jsonify( return generate_response(db.file_schema.jsonify(
new_file), OK_STATUS_CODE) new_file), OK_STATUS_CODE)
@app.route('/api/update_file/<file_id>', methods=['PUT']) @app.route('/api/update_file/<file_id>', methods=['PUT'])
@jwt_required @jwt_required
def update_file_request(file_id): def update_file_request(file_id):
# Update file
file = request.json['file'] file = request.json['file']
old_file = db.get_file(file['id'])
updated_file = db.File( updated_file = db.File(
file['projectId'], file['projectId'],
file['name'], file['name'],
...@@ -452,6 +471,21 @@ def update_file_request(file_id): ...@@ -452,6 +471,21 @@ def update_file_request(file_id):
project.edited = datetime.now() project.edited = datetime.now()
db.update_project(project) db.update_project(project)
# Update file locally on server if project is open
open_project_path = str(project.id) + '/'
if old_file.parent:
old_path = open_project_path + old_file.parent + '/' + old_file.name
else:
old_path = open_project_path + old_file.name
if os.path.exists(old_path):
with SimpleFlock(str(project.id) + 'lock', SIMPLE_FLOCK_TIMEOUT):
if os.path.exists(old_path):
if file['parent']:
new_path = open_project_path + file['parent'] + '/' + file['name']
else:
new_path = open_project_path + file['name']
os.rename(old_path, new_path)
return generate_response(db.file_schema.jsonify( return generate_response(db.file_schema.jsonify(
db.update_file(updated_file)), OK_STATUS_CODE) db.update_file(updated_file)), OK_STATUS_CODE)
...@@ -464,6 +498,20 @@ def delete_file_request(file_id): ...@@ -464,6 +498,20 @@ def delete_file_request(file_id):
project.edited = datetime.now() project.edited = datetime.now()
db.update_project(project) db.update_project(project)
# Remove file locally on server if project is open
open_project_path = str(file.projectId) + '/'
if file.parent:
path = open_project_path + file.parent + '/' + file.name
else:
path = open_project_path + file.name
if os.path.exists(path):
with SimpleFlock(str(file.projectId) + 'lock', SIMPLE_FLOCK_TIMEOUT):
if os.path.exists(path):
if file.isFolder:
shutil.rmtree(path)
else:
os.remove(path)
return generate_response(db.file_schema.jsonify( return generate_response(db.file_schema.jsonify(
db.delete_file(file_id)), OK_STATUS_CODE) db.delete_file(file_id)), OK_STATUS_CODE)
......
No preview for this file type
from __init__ import app import os, shutil
import database_helper as db
from flask import json from flask import json
from flask_socketio import SocketIO, send, emit, join_room, leave_room from flask_socketio import SocketIO, send, emit, join_room, leave_room
import diff_match_patch as dmp_module import diff_match_patch as dmp_module
from simpleflock import SimpleFlock
from __init__ import app
import database_helper as db
SIMPLE_FLOCK_TIMEOUT = 10
socketio = SocketIO(app) socketio = SocketIO(app)
dmp = dmp_module.diff_match_patch() dmp = dmp_module.diff_match_patch()
...@@ -150,6 +155,18 @@ def on_join_open_project_room(data): ...@@ -150,6 +155,18 @@ def on_join_open_project_room(data):
room = 'openProject' + str(project_id) room = 'openProject' + str(project_id)
join_room(room) join_room(room)
add_project_viewer(project_id, username) add_project_viewer(project_id, username)
if not os.path.exists(str(project_id)):
os.mkdir(str(project_id))
for file in db.get_project_files(project_id):
dir_name = str(project_id) + ('/' + file['parent'] if file['parent'] else '')
if not os.path.exists(dir_name):
os.makedirs(dir_name)
if not file['isFolder']:
f = open(dir_name + '/' + file['name'], "a+")
f.write(file['content'])
f.close()
emit('joinOpenProjectRoom', { emit('joinOpenProjectRoom', {
'on': 'joinOpenProjectRoom', 'on': 'joinOpenProjectRoom',
'username': username, 'username': username,
...@@ -164,6 +181,10 @@ def on_leave_open_project_room(data): ...@@ -164,6 +181,10 @@ def on_leave_open_project_room(data):
room = 'openProject' + str(project_id) room = 'openProject' + str(project_id)
leave_room(room) leave_room(room)
remove_project_viewer(project_id, username) remove_project_viewer(project_id, username)
if not project_viewers[str(project_id)] and os.path.exists(str(project_id)):
shutil.rmtree(str(project_id))
emit('leaveOpenProjectRoom', { emit('leaveOpenProjectRoom', {
'on': 'leaveOpenProjectRoom', 'on': 'leaveOpenProjectRoom',
'username': username, 'username': username,
...@@ -200,6 +221,20 @@ def handle_file_content_changed(data): ...@@ -200,6 +221,20 @@ def handle_file_content_changed(data):
file.content = dmp.patch_apply(patches, file.content)[0] file.content = dmp.patch_apply(patches, file.content)[0]
db.update_file(file) db.update_file(file)
# Update file locally on server if project is open
open_project_path = str(file.projectId) + '/'
if os.path.exists(open_project_path):
if file.parent:
file_path = open_project_path + file.parent + '/' + file.name
else:
file_path = open_project_path + file.name
if os.path.exists(file_path):
with SimpleFlock(str(file.projectId) + 'lock', SIMPLE_FLOCK_TIMEOUT):
if os.path.exists(file_path):
f = open(file_path, 'w')
f.write(file.content)
f.close()
emit('fileContentChanged', { emit('fileContentChanged', {
'on': 'fileContentChanged', 'on': 'fileContentChanged',
'projectId': project_id, 'projectId': project_id,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment