Skip to content

Commit

Permalink
Separated graph-related functions into a separate file. Cleaned a few…
Browse files Browse the repository at this point in the history
… functions up and added a few helper functions.
  • Loading branch information
TaaviE committed Apr 8, 2020
1 parent 2d3ac72 commit 445dda7
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 16 deletions.
13 changes: 7 additions & 6 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,12 @@ def use_identity(element, compiler, **kw):
# noinspection PyUnresolvedReferences
from models.enums import event_type_to_id, subscription_type_to_id, audit_event_type_to_id, wishlist_status_to_id

from views import static, login, views, user_specific, edit, test
from views import static_page, login_page, main_page, user_specific, edit_page, test_page, graph_page

app.register_blueprint(edit)
app.register_blueprint(login)
app.register_blueprint(static)
app.register_blueprint(test)
app.register_blueprint(static_page)
app.register_blueprint(login_page)
app.register_blueprint(main_page)
app.register_blueprint(user_specific)
app.register_blueprint(views)
app.register_blueprint(edit_page)
app.register_blueprint(test_page)
app.register_blueprint(graph_page)
2 changes: 1 addition & 1 deletion socketio_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from flask_socketio import disconnect


def authenticated_only(func: Callable[[Any], Any]) -> Callable[[Any], Any]:
def authenticated_only(func: Callable[[Any], Any]):
"""
@param func: function to decorate
@return: wrapped function
Expand Down
19 changes: 19 additions & 0 deletions utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
from sqlalchemy import and_

import sentry_sdk
from logging import getLogger

getLogger().setLevel(Config.LOGLEVEL)
logger = getLogger()


def get_user() -> User:
Expand Down Expand Up @@ -86,3 +90,18 @@ def get_person_language_code(user_id: int) -> str:
return "ee"
else:
return user.language


def commit_object(obj: object) -> bool:
"""
Commits an object to the DB and catches the potential error
"""
try:
db.session.add(obj)
db.session.commit()
return True
except Exception as e:
db.session.rollback()
sentry_sdk.capture_exception(e)
logger.error("Failed adding group")
return False
16 changes: 16 additions & 0 deletions utility_standalone.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Utility functions that aren't super specific to Loosindus
"""
import re
from uuid import UUID

import pyximport
from flask import session
Expand Down Expand Up @@ -99,3 +100,18 @@ def set_recursion_limit() -> None:
Sets the recustion limit required by shuffling
"""
setrecursionlimit(2000)


@lru_cache(maxsize=64)
def valid_uuid(uuid: str) -> bool:
"""
Checks if the UUID is sane
"""
if len(uuid) != 36:
return False

try:
UUID(uuid)
return True
except Exception:
return False
13 changes: 7 additions & 6 deletions views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
"""
Contains all the views used in Loosindus
"""
from views.edit.blueprint import edit_page as edit
from views.login import login_page as login
from views.static import static_page as static
from views.test import test_page as test
from views.user_specific_static import user_specific as user_specific
from views.views import main_page as views
from views.edit.blueprint import edit_page
from views.graph import graph_page
from views.login import login_page
from views.static import static_page
from views.test import test_page
from views.user_specific_static import user_specific
from views.views import main_page
144 changes: 144 additions & 0 deletions views/graph.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# coding=utf-8
# Copyright: Taavi Eomäe 2017-2020
# SPDX-License-Identifier: AGPL-3.0-only
"""
Contains all of the routes that deal with displaying graphs
"""
from json import dumps
from logging import getLogger

import sentry_sdk
from flask import Blueprint, render_template, request
from flask_babelex import gettext as _
from flask_security import login_required
from sqlalchemy import and_

from config import Config
from models.shuffles_model import Shuffle
from utility_standalone import get_christmasy_emoji, get_user_id

graph_page = Blueprint("graph_page",
__name__,
template_folder="templates")

getLogger().setLevel(Config.LOGLEVEL)
logger = getLogger()


@graph_page.route("/graph")
@login_required
def graph():
"""
Display default group's graph
"""
user_id = get_user_id()
try:
if "group_id" in request.args.keys():
family_group = request.args["group_id"]
else:
family = get_default_family(user_id)
family_group = FamilyGroup.query.filter(and_(FamilyGroup.family_id == family.id,
FamilyGroup.confirmed == True)
).one().group_id

if "unhide" in request.args.keys(): # TODO: Make prettier
if request.args["unhide"] in "True":
unhide = "True"
user_number = _("or with your own name")
else:
unhide = ""
user_number = get_christmasy_emoji(user_id)
else:
unhide = ""
user_number = get_christmasy_emoji(user_id)
return render_template("graph.html",
id=user_number,
graph_id=family_group,
unhide=unhide,
title=_("Graph"))
except Exception as e:
sentry_sdk.capture_exception(e)
return render_template("utility/error.html",
message=
_("Shuffling has not yet been done for your group (or some other error occured)!"),
title=
_("Error"),
no_video=True)


@graph_page.route("/graph/<event_id>/<unhide>")
@graph_page.route("/graph/<event_id>", defaults={"unhide": False})
@graph_page.route("/graph/<event_id>/", defaults={"unhide": False})
@login_required
def graph_json(event_id, unhide):
"""
Displays an interactive graph
"""
user_id = int(session["user_id"])

try:
group_id = int(event_id)
if unhide == "True":
user_group_admin = UserGroupAdmin.query.filter(and_(UserGroupAdmin.user_id == user_id,
UserGroupAdmin.group_id == int(group_id),
UserGroupAdmin.confirmed == True)
).one()
if user_group_admin is not None and user_group_admin.admin:
unhide = True
else:
unhide = False

belongs_in_group = False
people = {"nodes": [], "links": []}
current_year = datetime.datetime.now().year
database_families = get_families_in_group(group_id)

for family in database_families:
for user in UserFamilyAdmin.query.filter(and_(UserFamilyAdmin.family_id == family.id,
UserFamilyAdmin.confirmed == True)).all():
if unhide:
people["nodes"].append({"id": get_person_name(user.user_id),
"group": family.id})
else:
if user.user_id == user_id:
belongs_in_group = True
people["nodes"].append({"id": get_christmasy_emoji(user.user_id),
"group": 2})
else:
people["nodes"].append({"id": get_christmasy_emoji(user.user_id),
"group": 1})

shuffles = Shuffle.query.filter(and_(Shuffle.giver == user.user_id, Shuffle.year == current_year)).all()
for shuffle_element in shuffles:
if unhide:
people["links"].append({"source": get_person_name(shuffle_element.giver),
"target": get_person_name(shuffle_element.getter),
"value": 0})
else:
people["links"].append(
{"source": get_christmasy_emoji(shuffle_element.giver),
"target": get_christmasy_emoji(shuffle_element.getter),
"value": 0})

if belongs_in_group or unhide:
return dumps(people), 200, {"content-type": "application/json"}
else:
return "{}", 200, {"content-type": "application/json"}
except Exception as e:
sentry_sdk.capture_exception(e)
return "{}", 200, {"content-type": "application/json"}


@graph_page.route("/grapher/<graph_id>/<unhide>")
@graph_page.route("/grapher/<graph_id>", defaults={"unhide": ""})
@graph_page.route("/grapher/<graph_id>/", defaults={"unhide": ""})
@login_required
def graph_js(graph_id, unhide):
"""
Returns the JS required to graph one specific graph
"""
return render_template(
"grapher.js",
graph_id=graph_id,
unhide=unhide
), 200, {"content-type": "application/javascript"}
9 changes: 6 additions & 3 deletions websockets.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
"""
Contains websocket related code
"""
import eventlet
from eventlet import monkey_patch
from flask import Flask
from flask_socketio import SocketIO
from flask_login import current_user
from flask_socketio import SocketIO, emit

from config import Config
from socketio_helper import authenticated_only

eventlet.monkey_patch()
# Do eventlet monkey patching
monkey_patch()

app = Flask(__name__)
app.config.from_object(Config)
Expand Down

0 comments on commit 445dda7

Please sign in to comment.