-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathutils.py
152 lines (128 loc) · 4.11 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
from __future__ import annotations
from sqlalchemy.orm import Session
from datetime import datetime, timedelta
from flask import render_template as _render_template
from flask import request
from PIL import Image
from app.common.database.repositories import wrapper
from app.common.database import DBUser, DBBeatmapset
from app.common.helpers.external import location
from app.common.cache import leaderboards
from app.common.helpers import caching
from app.common import constants
from app.common.database import (
notifications,
repositories,
histories,
topics,
stats
)
import flask_login
import config
import app
import io
def render_template(template_name: str, **context) -> str:
"""This will automatically append the required data to the context for rendering pages"""
total_scores = 0
online_users = 0
total_users = 0
try:
total_scores = int(app.session.redis.get('bancho:totalscores') or 0)
online_users = int(app.session.redis.get('bancho:users') or 0)
total_users = int(app.session.redis.get('bancho:totalusers') or 0)
except Exception as e:
# Most likely failed to connect to redis instance
app.session.logger.error(
f'Failed to fetch bancho stats: {e}',
exc_info=e
)
context.update(
is_compact=request.args.get('compact', 0, type=int) == 1,
show_login=request.args.get('login', False, type=bool),
total_scores=total_scores,
online_users=online_users,
total_users=total_users,
repositories=repositories,
timedelta=timedelta,
constants=constants,
datetime=datetime,
location=location,
config=config
)
if not flask_login.current_user.is_anonymous:
context.update({
'notification_count': notifications.fetch_count(
flask_login.current_user.id,
read=False
)
})
return _render_template(
template_name,
**context
)
@caching.ttl_cache(ttl=900)
def fetch_average_topic_views() -> int:
return int(topics.fetch_average_views())
def on_sync_ranks_fail(e: Exception) -> None:
app.session.logger.error(
f'Failed to update user rank: {e}',
exc_info=e
)
@wrapper.exception_wrapper(on_sync_ranks_fail)
@wrapper.session_wrapper
def sync_ranks(user: DBUser, session: Session | None = None) -> None:
"""Sync cached rank with database"""
for user_stats in user.stats:
if user_stats.playcount <= 0:
continue
global_rank = leaderboards.global_rank(
user.id,
user_stats.mode
)
if user_stats.rank != global_rank:
# Database rank desynced from redis
stats.update(
user.id,
user_stats.mode,
{'rank': global_rank},
session=session
)
user_stats.rank = global_rank
# Update rank history
histories.update_rank(
user_stats,
user.country,
session=session
)
def required_nominations(beatmapset: DBBeatmapset) -> bool:
beatmap_modes = len(
set(
beatmap.mode
for beatmap in beatmapset.beatmaps
)
)
# NOTE: Beatmap requires 2 approvals + 1 for each other mode
additional_modes = beatmap_modes - 1
required_nominations = 2 + additional_modes
return required_nominations
def resize_image(
image: bytes,
target_width: int | None = None,
target_height: int | None = None
) -> bytes:
image_buffer = io.BytesIO()
img = Image.open(io.BytesIO(image))
img = img.resize((target_width, target_height))
img.save(image_buffer, format='JPEG')
return image_buffer.getvalue()
def empty_image(
width: int,
height: int
) -> bytes:
image_buffer = io.BytesIO()
img = Image.new('RGB', (width, height), (0, 0, 0))
img.save(image_buffer, format='JPEG')
return image_buffer.getvalue()
@caching.ttl_cache(ttl=900)
def fetch_average_topic_views() -> int:
return int(topics.fetch_average_views())