add better implementation for GET /voice/region

this takes account of:
 - the majority region selected in all the guilds the user owns. if that
    fails:
 - the majority region on all the guilds the user is in. if that fails:
 - random region

 - storage: add Storage.all_voice_regions
This commit is contained in:
Luna 2019-03-03 18:57:54 -03:00
parent 42cd0ae12c
commit 7fdb74370e
2 changed files with 93 additions and 4 deletions

View File

@ -17,13 +17,93 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from quart import Blueprint, jsonify
from collections import Counter
from random import choice
from quart import Blueprint, jsonify, current_app as app
from litecord.blueprints.auth import token_check
bp = Blueprint('voice', __name__)
def _majority_region_count(regions: list) -> str:
"""Return the first most common element in a given list."""
counter = Counter(regions)
common = counter.most_common(1)
region, _count = common[0]
return region
async def _choose_random_region() -> str:
"""Give a random voice region."""
regions = await app.db.fetchval("""
SELECT id
FROM voice_regions
""")
regions = [r['id'] for r in regions]
if not regions:
return None
return choice(regions)
async def _majority_region_any(user_id) -> str:
"""Calculate the most likely region to make the user happy, but
this is based on the guilds the user is IN, instead of the guilds
the user owns."""
guilds = await app.storage.get_user_guilds(user_id)
if not guilds:
return await _choose_random_region()
res = []
for guild_id in guilds:
region = await app.db.fetchval("""
SELECT region
FROM guilds
WHERE id = $1
""", guild_id)
res.append(region)
most_common = _majority_region_count(res)
if most_common is None:
return await _choose_random_region()
return most_common
async def majority_region(user_id) -> str:
"""Given a user ID, give the most likely region for the user to be
happy with."""
regions = await app.db.fetch("""
SELECT region
FROM guilds
WHERE owner_id = $1
""", user_id)
if not regions:
return await _majority_region_any(user_id)
regions = [r['region'] for r in regions]
return _majority_region_count(regions)
@bp.route('/regions', methods=['GET'])
async def voice_regions():
return jsonify([
{'name': 'Brazil', 'deprecated': False, 'id': 'Brazil', 'optimal': True, 'vip': True}
])
"""Return voice regions."""
user_id = await token_check()
best_region = await majority_region(user_id)
regions = await app.storage.get_all_regions()
for region in regions:
region['optimal'] = region['id'] == best_region
return jsonify(regions)

View File

@ -1015,3 +1015,12 @@ class Storage:
""", role_id)
return [r['id'] for r in rows]
async def all_voice_regions(self) -> List[Dict[str, Any]]:
"""Return a list of all voice regions."""
rows = await self.db.fetch("""
SELECT id, name, vip, deprecated, custom
FROM voice_regions
""")
return list(map(dict, rows))