Skip to content

Commit 69080a3

Browse files
authored
Merge pull request #107 from JoelEager/the-great-refactor-round-2
Cache cleanup and general refactoring
2 parents b50a5fa + 45b20bf commit 69080a3

File tree

9 files changed

+62
-112
lines changed

9 files changed

+62
-112
lines changed

packet/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
logging.getLogger().setLevel(app.config["LOG_LEVEL"])
3232
app.logger.info("Launching packet v" + app.config["VERSION"])
3333

34+
app.logger.info("Using the {} realm".format(app.config["REALM"]))
35+
3436
# Initialize the extensions
3537
db = SQLAlchemy(app)
3638
migrate = Migrate(app, db)

packet/commands.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Defines command-line utilities for use with the app
2+
Defines command-line utilities for use with packet
33
"""
44

55
from secrets import token_hex

packet/context_processors.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212

1313
# pylint: disable=bare-except
14-
@lru_cache(maxsize=128)
1514
def get_csh_name(username):
1615
try:
1716
member = ldap_get_member(username)

packet/ldap.py

Lines changed: 7 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
"""
2+
Helper functions for working with the csh_ldap library
3+
"""
4+
15
from functools import lru_cache
26

37
from packet import _ldap
48

59

6-
@lru_cache(maxsize=1024)
710
def _ldap_get_group_members(group):
811
return _ldap.get_group(group).get_members()
912

@@ -16,48 +19,21 @@ def _ldap_is_member_of_group(member, group):
1619
return False
1720

1821

19-
@lru_cache(maxsize=1024)
20-
def _ldap_is_member_of_directorship(account, directorship):
21-
directors = _ldap.get_directorship_heads(directorship)
22-
for director in directors:
23-
if director.uid == account.uid:
24-
return True
25-
return False
26-
27-
2822
# Getters
2923

30-
@lru_cache(maxsize=4096)
24+
@lru_cache(maxsize=256)
3125
def ldap_get_member(username):
3226
return _ldap.get_member(username, uid=True)
3327

3428

35-
@lru_cache(maxsize=1024)
3629
def ldap_get_active_members():
3730
return _ldap_get_group_members("active")
3831

3932

40-
@lru_cache(maxsize=1024)
4133
def ldap_get_intro_members():
4234
return _ldap_get_group_members("intromembers")
4335

4436

45-
@lru_cache(maxsize=1024)
46-
def ldap_get_onfloor_members():
47-
return _ldap_get_group_members("onfloor")
48-
49-
50-
@lru_cache(maxsize=1024)
51-
def ldap_get_groups(account):
52-
group_list = account.get("memberOf")
53-
groups = []
54-
for group_dn in group_list:
55-
if "cn=groups,cn=accounts" in group_dn:
56-
groups.append(group_dn.split(",")[0][3:])
57-
return groups
58-
59-
60-
@lru_cache(maxsize=1024)
6137
def ldap_get_eboard():
6238
members = _ldap_get_group_members("eboard-chairman") + _ldap_get_group_members("eboard-evaluations"
6339
) + _ldap_get_group_members("eboard-financial") + _ldap_get_group_members("eboard-history"
@@ -68,63 +44,28 @@ def ldap_get_eboard():
6844
return members
6945

7046

71-
@lru_cache(maxsize=2048)
7247
def ldap_get_live_onfloor():
7348
"""
7449
:return: All upperclassmen who live on floor and are not eboard
7550
"""
7651
members = []
77-
onfloor = ldap_get_onfloor_members()
52+
onfloor = _ldap_get_group_members("onfloor")
7853
for member in onfloor:
7954
if ldap_get_roomnumber(member) and not ldap_is_eboard(member):
8055
members.append(member)
56+
8157
return members
8258

8359

8460
# Status checkers
8561

86-
@lru_cache(maxsize=1024)
87-
def ldap_is_eval_director(account):
88-
return _ldap_is_member_of_directorship(account, 'evaluations')
89-
90-
91-
@lru_cache(maxsize=1024)
92-
def ldap_is_active(account):
93-
return _ldap_is_member_of_group(account, 'active')
94-
95-
96-
@lru_cache(maxsize=1024)
97-
def ldap_is_alumni(account):
98-
# If the user is not active, they are an alumni.
99-
return not _ldap_is_member_of_group(account, 'active')
100-
101-
102-
@lru_cache(maxsize=1024)
10362
def ldap_is_eboard(account):
10463
return _ldap_is_member_of_group(account, 'eboard')
10564

10665

107-
@lru_cache(maxsize=1024)
108-
def ldap_is_rtp(account):
109-
return _ldap_is_member_of_group(account, 'rtp')
110-
111-
112-
@lru_cache(maxsize=1024)
11366
def ldap_is_intromember(account):
11467
return _ldap_is_member_of_group(account, 'intromembers')
11568

116-
117-
@lru_cache(maxsize=1024)
118-
def ldap_is_onfloor(account):
119-
return _ldap_is_member_of_group(account, 'onfloor')
120-
121-
122-
@lru_cache(maxsize=1024)
123-
def ldap_is_current_student(account):
124-
return _ldap_is_member_of_group(account, 'current_student')
125-
126-
127-
@lru_cache(maxsize=1024)
12869
def ldap_get_roomnumber(account):
12970
try:
13071
return account.roomNumber

packet/log_utils.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
from functools import wraps
66
from datetime import datetime
77

8-
from packet import context_processors, app
8+
from packet import app
9+
from packet.context_processors import get_rit_name
10+
from packet.ldap import ldap_get_member
11+
from packet.utils import is_freshman_on_floor
912

1013

1114
def log_time(func):
@@ -26,16 +29,29 @@ def wrapped_function(*args, **kwargs):
2629
return wrapped_function
2730

2831

32+
def _format_cache(func):
33+
"""
34+
:return: The output of func.cache_info() as a compactly formatted string
35+
"""
36+
info = func.cache_info()
37+
return "{}[hits={}, misses={}, size={}/{}]".format(func.__name__, info.hits, info.misses, info.currsize,
38+
info.maxsize)
39+
40+
41+
# Tuple of lru_cache functions to log stats from
42+
_caches = (get_rit_name, ldap_get_member, is_freshman_on_floor)
43+
44+
2945
def log_cache(func):
3046
"""
3147
Decorator for logging cache info
3248
"""
49+
3350
@wraps(func)
3451
def wrapped_function(*args, **kwargs):
3552
result = func(*args, **kwargs)
3653

37-
app.logger.info("get_csh_name(): {}, get_rit_name(): {}".format(context_processors.get_csh_name.cache_info(),
38-
context_processors.get_rit_name.cache_info()))
54+
app.logger.info("Cache stats: " + ", ".join(map(_format_cache, _caches)))
3955

4056
return result
4157

packet/models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Defines the application's database models.
2+
Defines the application's database models
33
"""
44

55
from datetime import datetime
@@ -107,7 +107,7 @@ def is_100(self):
107107
"""
108108
Checks if this packet has reached 100%
109109
"""
110-
return self.signatures_required().total == self.signatures_recieved().total
110+
return self.signatures_required().total == self.signatures_received().total
111111

112112
@classmethod
113113
def open_packets(cls):

packet/routes/api.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
"""
2+
Shared API endpoints
3+
"""
4+
15
from packet import app, db
26
from packet.utils import before_request, packet_auth, notify_slack
37
from packet.models import Packet, MiscSignature

packet/routes/shared.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ def freshman_packet(packet_id, info=None):
4545
upper=filter(lambda sig: not sig.eboard, packet.upper_signatures))
4646

4747

48+
def packet_sort_key(packet):
49+
"""
50+
Utility function for generating keys for sorting packets
51+
"""
52+
return packet.signatures_received_result.total, packet.did_sign_result
53+
54+
4855
@app.route("/packets/")
4956
@log_cache
5057
@packet_auth
@@ -59,7 +66,6 @@ def packets(info=None):
5966
packet.signatures_received_result = packet.signatures_received()
6067
packet.signatures_required_result = packet.signatures_required()
6168

62-
open_packets.sort(key=lambda packet: packet.signatures_received_result.total, reverse=True)
63-
open_packets.sort(key=lambda packet: packet.did_sign_result, reverse=True)
69+
open_packets.sort(key=packet_sort_key, reverse=True)
6470

6571
return render_template("active_packets.html", info=info, packets=open_packets)

packet/utils.py

Lines changed: 19 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
# Credit to Liam Middlebrook and Ram Zallan
2-
# https://github.com/liam-middlebrook/gallery
1+
"""
2+
General utilities and decorators for supporting the Python logic
3+
"""
4+
35
from functools import wraps, lru_cache
46

57
import requests
68
from flask import session
79

8-
from packet import _ldap, auth, app
10+
from packet import auth, app
911
from packet.models import Freshman
10-
from packet.ldap import (ldap_get_member,
11-
ldap_is_active,
12-
ldap_is_onfloor,
13-
ldap_get_roomnumber,
14-
ldap_get_groups,
15-
ldap_is_intromember)
12+
from packet.ldap import ldap_get_member, ldap_is_intromember
1613

1714
INTRO_REALM = "https://sso.csh.rit.edu/auth/realms/intro"
1815

19-
2016
def before_request(func):
17+
"""
18+
Credit to Liam Middlebrook and Ram Zallan
19+
https://github.com/liam-middlebrook/gallery
20+
"""
2121
@wraps(func)
2222
def wrapped_function(*args, **kwargs):
2323
uid = str(session["userinfo"].get("preferred_username", ""))
@@ -26,18 +26,12 @@ def wrapped_function(*args, **kwargs):
2626
info = {
2727
"realm": "intro",
2828
"uid": uid,
29-
"onfloor": is_on_floor(uid)
29+
"onfloor": is_freshman_on_floor(uid)
3030
}
3131
else:
32-
uuid = str(session["userinfo"].get("sub", ""))
33-
user_obj = _ldap.get_member(uid, uid=True)
3432
info = {
3533
"realm": "csh",
36-
"uuid": uuid,
37-
"uid": uid,
38-
"user_obj": user_obj,
39-
"member_info": get_member_info(uid),
40-
"color": requests.get('https://themeswitcher.csh.rit.edu/api/colour').content
34+
"uid": uid
4135
}
4236

4337
kwargs["info"] = info
@@ -46,25 +40,12 @@ def wrapped_function(*args, **kwargs):
4640
return wrapped_function
4741

4842

49-
@lru_cache(maxsize=2048)
50-
def get_member_info(uid):
51-
account = ldap_get_member(uid)
52-
53-
member_info = {
54-
"user_obj": account,
55-
"group_list": ldap_get_groups(account),
56-
"uid": account.uid,
57-
"name": account.cn,
58-
"active": ldap_is_active(account),
59-
"onfloor": ldap_is_onfloor(account),
60-
"room": ldap_get_roomnumber(account),
61-
}
62-
return member_info
63-
64-
65-
@lru_cache(maxsize=2048)
66-
def is_on_floor(uid):
67-
freshman = Freshman.query.filter_by(rit_username=uid).first()
43+
@lru_cache(maxsize=128)
44+
def is_freshman_on_floor(rit_username):
45+
"""
46+
Checks if a freshman is on floor
47+
"""
48+
freshman = Freshman.query.filter_by(rit_username=rit_username).first()
6849
if freshman is not None:
6950
return freshman.onfloor
7051
else:
@@ -88,6 +69,7 @@ def wrapped_function(*args, **kwargs):
8869

8970
return wrapped_function
9071

72+
9173
def notify_slack(name: str):
9274
"""
9375
Sends a congratulate on sight decree to Slack

0 commit comments

Comments
 (0)