blueprints.users: use Storage.get_user_settings

paving the way for user settings support.

 - storage: add Storage.get_user_settings
 - storage: add methods to fetch with json/jsonb codecs enabled
This commit is contained in:
Luna Mendes 2018-09-29 23:10:42 -03:00
parent 4841565f14
commit 624eb6eb0e
3 changed files with 62 additions and 32 deletions

View File

@ -136,38 +136,10 @@ async def put_note(target_id: int):
@bp.route('/@me/settings', methods=['GET'])
async def get_user_settings():
# TODO: for now, just return hardcoded defaults,
# once we get the user_settings table working
# we can move to that.
await token_check()
return jsonify({
'afk_timeout': 300,
'animate_emoji': True,
'convert_emoticons': False,
'default_guilds_restricted': True,
'detect_platform_accounts': False,
'developer_mode': True,
'disable_games_tab': True,
'enable_tts_command': False,
'explicit_content_filter': 2,
'friend_source_flags': {
'mutual_friends': True
},
'gif_auto_play': True,
'guild_positions': [],
'restricted_guilds': [],
'inline_attachment_media': True,
'inline_embed_media': True,
'locale': 'en-US',
'message_display_compact': False,
'render_embeds': True,
'render_reactions': True,
'show_current_game': True,
'status': 'online',
'theme': 'dark',
'timezone_offset': 420,
})
"""Get the current user's settings."""
user_id = await token_check()
settings = await app.storage.get_user_settings(user_id)
return jsonify(settings)
@bp.route('/@me/settings', methods=['PATCH'])

View File

@ -1,3 +1,4 @@
import json
from typing import List, Dict, Any
from logbook import Logger
@ -17,12 +18,45 @@ def dict_(val):
return dict(val) if val else None
async def _set_json(con):
"""Set JSON and JSONB codecs for an
asyncpg connection."""
await con.set_type_codec(
'json',
encoder=json.dumps,
decoder=json.loads,
schema='pg_catalog'
)
await con.set_type_codec(
'jsonb',
encoder=json.dumps,
decoder=json.loads,
schema='pg_catalog'
)
class Storage:
"""Class for common SQL statements."""
def __init__(self, db):
self.db = db
self.presence = None
async def _fetchrow_with_json(self, query: str, *args):
"""Fetch a single row with JSON/JSONB support."""
# the pool by itself doesn't have
# set_type_codec, so we must set it manually
# by acquiring the connection
async with self.db.acquire() as con:
await _set_json(con)
return await con.fetchrow(query, *args)
async def _fetch_with_json(self, query: str, *args):
"""Fetch many rows with JSON/JSONB support."""
async with self.db.acquire() as con:
await _set_json(con)
return await con.fetch(query, *args)
async def get_user(self, user_id, secure=False) -> Dict[str, Any]:
"""Get a single user payload."""
user_id = int(user_id)
@ -500,3 +534,26 @@ class Storage:
dinv['inviter'] = inviter
return dinv
async def get_user_settings(self, user_id: int) -> Dict[str, Any]:
row = await self._fetchrow_with_json("""
SELECT *
FROM user_settings
WHERE id = $1
""", user_id)
if not row:
log.info('Generating user settings for {}', user_id)
await self.db.execute("""
INSERT INTO user_settings (id)
VALUES ($1)
""", user_id)
# recalling get_user_settings
# should work after adding
return await self.get_user_settings(user_id)
drow = dict(row)
drow.pop('id')
return drow

1
run.py
View File

@ -83,6 +83,7 @@ async def app_after_request(resp):
async def app_before_serving():
log.info('opening db')
app.db = await asyncpg.create_pool(**app.config['POSTGRES'])
g.app = app
app.loop = asyncio.get_event_loop()