mirror of
https://github.com/arcan1s/ffxivbis.git
synced 2025-04-25 09:47:18 +00:00
some party impl
This commit is contained in:
parent
2d84459c4d
commit
4ff985bf81
75
migrations/20190916_01_zGTB1-party-id.py
Normal file
75
migrations/20190916_01_zGTB1-party-id.py
Normal file
@ -0,0 +1,75 @@
|
||||
'''
|
||||
party id
|
||||
'''
|
||||
|
||||
import random
|
||||
import string
|
||||
|
||||
from yoyo import step
|
||||
|
||||
__depends__ = {'20190830_01_sYYZL-init-tables', '20190910_01_tgBmx-users-table'}
|
||||
party_id = ''.join(random.sample(string.ascii_letters, 16))
|
||||
|
||||
steps = [
|
||||
step('''create table players2 (
|
||||
party_id text not null,
|
||||
player_id integer primary key,
|
||||
created integer not null,
|
||||
nick text not null,
|
||||
job text not null,
|
||||
bis_link text,
|
||||
priority integer not null default 1
|
||||
)'''),
|
||||
# not safe for injections, but sqlite and psycopg have different placeholders for parameters
|
||||
step('''insert into players2 select '%s' as party_id, players.* from players''' % (party_id,)),
|
||||
step('''drop index if exists players_nick_job_idx'''),
|
||||
step('''create unique index players_nick_job_idx on players2(party_id, nick, job)'''),
|
||||
|
||||
step('''create table loot2 (
|
||||
loot_id integer primary key,
|
||||
player_id integer not null,
|
||||
created integer not null,
|
||||
piece text not null,
|
||||
is_tome integer not null,
|
||||
foreign key (player_id) references players2(player_id) on delete cascade
|
||||
)'''),
|
||||
step('''insert into loot2 select * from loot'''),
|
||||
step('''drop index if exists loot_owner_idx'''),
|
||||
step('''create index loot_owner_idx on loot(player_id)'''),
|
||||
|
||||
step('''create table bis2 (
|
||||
player_id integer not null,
|
||||
created integer not null,
|
||||
piece text not null,
|
||||
is_tome integer not null,
|
||||
foreign key (player_id) references players2(player_id) on delete cascade
|
||||
)'''),
|
||||
step('''insert into bis2 select * from bis'''),
|
||||
step('''drop index if exists bis_piece_player_id_idx'''),
|
||||
step('''create unique index bis_piece_player_id_idx on bis2(player_id, piece)'''),
|
||||
|
||||
step('''create table users2 (
|
||||
party_id text not null,
|
||||
user_id integer primary key,
|
||||
username text not null,
|
||||
password text not null,
|
||||
permission text not null,
|
||||
foreign key (party_id) references players2(party_id) on delete cascade
|
||||
)'''),
|
||||
# not safe for injections, but sqlite and psycopg have different placeholders for parameters
|
||||
step('''insert into users2 select '%s' as party_id, users.* from users''' % (party_id,)),
|
||||
step('''drop index if exists users_username_idx'''),
|
||||
step('''create unique index users_username_idx on users2(party_id, username)'''),
|
||||
|
||||
step('''drop table users'''),
|
||||
step('''alter table users2 rename to users'''),
|
||||
|
||||
step('''drop table loot'''),
|
||||
step('''alter table loot2 rename to loot'''),
|
||||
|
||||
step('''drop table bis'''),
|
||||
step('''alter table bis2 rename to bis'''),
|
||||
|
||||
step('''drop table players'''),
|
||||
step('''alter table players2 rename to players''')
|
||||
]
|
@ -7,4 +7,4 @@ priority = is_required loot_count_bis loot_priority loot_count loot_count_total
|
||||
[web]
|
||||
host = 0.0.0.0
|
||||
port = 8000
|
||||
templates = templates
|
||||
templates = /home/arcanis/Documents/github/ffxivbis/templates
|
@ -8,7 +8,7 @@
|
||||
#
|
||||
from aiohttp.web import middleware, Request, Response
|
||||
from aiohttp_security import AbstractAuthorizationPolicy, check_permission
|
||||
from typing import Callable, Optional
|
||||
from typing import Callable, Optional, Tuple
|
||||
|
||||
from ffxivbis.core.database import Database
|
||||
|
||||
@ -18,12 +18,19 @@ class AuthorizationPolicy(AbstractAuthorizationPolicy):
|
||||
def __init__(self, database: Database) -> None:
|
||||
self.database = database
|
||||
|
||||
def split_identity(self, identity: str) -> Tuple[str, str]:
|
||||
# identity is party_id + username
|
||||
party_id, username = identity.split('+')
|
||||
return party_id, username
|
||||
|
||||
async def authorized_userid(self, identity: str) -> Optional[str]:
|
||||
user = await self.database.get_user(identity)
|
||||
return identity if user is not None else None
|
||||
party_id, username = self.split_identity(identity)
|
||||
user = await self.database.get_user(party_id, username)
|
||||
return username if user is not None else None
|
||||
|
||||
async def permits(self, identity: str, permission: str, context: str = None) -> bool:
|
||||
user = await self.database.get_user(identity)
|
||||
party_id, username = self.split_identity(identity)
|
||||
user = await self.database.get_user(party_id, username)
|
||||
if user is None:
|
||||
return False
|
||||
if user.username != identity:
|
||||
|
@ -25,21 +25,21 @@ from .views.html.users import UsersHtmlView
|
||||
|
||||
def setup_routes(app: Application) -> None:
|
||||
# api routes
|
||||
app.router.add_delete('/admin/api/v1/login/{username}', LoginView)
|
||||
app.router.add_post('/api/v1/login', LoginView)
|
||||
app.router.add_post('/api/v1/logout', LogoutView)
|
||||
app.router.add_put('/admin/api/v1/login', LoginView)
|
||||
app.router.add_delete('/admin/api/v1/{party_id}/login/{username}', LoginView)
|
||||
app.router.add_post('/api/v1/{party_id}/login', LoginView)
|
||||
app.router.add_post('/api/v1/{party_id}/logout', LogoutView)
|
||||
app.router.add_put('/admin/api/v1/{party_id}/login', LoginView)
|
||||
|
||||
app.router.add_get('/api/v1/party', PlayerView)
|
||||
app.router.add_post('/api/v1/party', PlayerView)
|
||||
app.router.add_get('/api/v1/party/{party_id}', PlayerView)
|
||||
app.router.add_post('/api/v1/party/{party_id}', PlayerView)
|
||||
|
||||
app.router.add_get('/api/v1/party/bis', BiSView)
|
||||
app.router.add_post('/api/v1/party/bis', BiSView)
|
||||
app.router.add_put('/api/v1/party/bis', BiSView)
|
||||
app.router.add_get('/api/v1/party/{party_id}/bis', BiSView)
|
||||
app.router.add_post('/api/v1/party/{party_id}/bis', BiSView)
|
||||
app.router.add_put('/api/v1/party/{party_id}/bis', BiSView)
|
||||
|
||||
app.router.add_get('/api/v1/party/loot', LootView)
|
||||
app.router.add_post('/api/v1/party/loot', LootView)
|
||||
app.router.add_put('/api/v1/party/loot', LootView)
|
||||
app.router.add_get('/api/v1/party/{party_id}/loot', LootView)
|
||||
app.router.add_post('/api/v1/party/{party_id}/loot', LootView)
|
||||
app.router.add_put('/api/v1/party/{party_id}/loot', LootView)
|
||||
|
||||
# html routes
|
||||
app.router.add_get('/', IndexHtmlView)
|
||||
@ -48,19 +48,19 @@ def setup_routes(app: Application) -> None:
|
||||
app.router.add_get('/api-docs', ApiHtmlView)
|
||||
app.router.add_get('/api-docs/swagger.json', ApiDocVIew)
|
||||
|
||||
app.router.add_get('/party', PlayerHtmlView)
|
||||
app.router.add_post('/party', PlayerHtmlView)
|
||||
app.router.add_get('/party/{party_id}', PlayerHtmlView)
|
||||
app.router.add_post('/party/{party_id}', PlayerHtmlView)
|
||||
|
||||
app.router.add_get('/bis', BiSHtmlView)
|
||||
app.router.add_post('/bis', BiSHtmlView)
|
||||
app.router.add_get('/bis/{party_id}', BiSHtmlView)
|
||||
app.router.add_post('/bis/{party_id}', BiSHtmlView)
|
||||
|
||||
app.router.add_get('/loot', LootHtmlView)
|
||||
app.router.add_post('/loot', LootHtmlView)
|
||||
app.router.add_get('/loot/{party_id}', LootHtmlView)
|
||||
app.router.add_post('/loot/{party_id}', LootHtmlView)
|
||||
|
||||
app.router.add_get('/suggest', LootSuggestHtmlView)
|
||||
app.router.add_post('/suggest', LootSuggestHtmlView)
|
||||
app.router.add_get('/suggest/{party_id}', LootSuggestHtmlView)
|
||||
app.router.add_post('/suggest/{party_id}', LootSuggestHtmlView)
|
||||
|
||||
app.router.add_get('/admin/users', UsersHtmlView)
|
||||
app.router.add_post('/admin/users', UsersHtmlView)
|
||||
app.router.add_get('/admin/users/{party_id}', UsersHtmlView)
|
||||
app.router.add_post('/admin/users/{party_id}', UsersHtmlView)
|
||||
|
||||
|
||||
|
@ -126,12 +126,13 @@ class LoginView(LoginBaseView, OpenApi):
|
||||
except Exception:
|
||||
data = dict(await self.request.post())
|
||||
|
||||
required = ['username', 'password']
|
||||
required = ['username', 'password', 'party_id']
|
||||
if any(param not in data for param in required):
|
||||
return wrap_invalid_param(required, data)
|
||||
|
||||
try:
|
||||
await self.create_user(data['username'], data['password'], data.get('permission', 'get'))
|
||||
await self.create_user(data['party_id'], data['username'],
|
||||
data['password'], data.get('permission', 'get'))
|
||||
except Exception as e:
|
||||
self.request.app.logger.exception('cannot create user')
|
||||
return wrap_exception(e, data)
|
||||
|
@ -21,8 +21,8 @@ class LoginBaseView(View):
|
||||
return False
|
||||
return md5_crypt.verify(password, user.password)
|
||||
|
||||
async def create_user(self, username: str, password: str, permission: str) -> None:
|
||||
await self.request.app['database'].insert_user(User(username, password, permission), False)
|
||||
async def create_user(self, party_id: str, username: str, password: str, permission: str) -> None:
|
||||
await self.request.app['database'].insert_user(party_id, User(username, password, permission), False)
|
||||
|
||||
async def login(self, username: str, password: str) -> None:
|
||||
if await self.check_credentials(username, password):
|
||||
|
@ -16,8 +16,7 @@ from aiohttp_security import CookiesIdentityPolicy
|
||||
|
||||
from ffxivbis.core.config import Configuration
|
||||
from ffxivbis.core.database import Database
|
||||
from ffxivbis.core.loot_selector import LootSelector
|
||||
from ffxivbis.core.party import Party
|
||||
from ffxivbis.core.party_aggregator import PartyAggregator
|
||||
|
||||
from .auth import AuthorizationPolicy, authorize_factory
|
||||
from .routes import setup_routes
|
||||
@ -35,7 +34,7 @@ def run_server(app: web.Application) -> None:
|
||||
port=app['config'].getint('web', 'port'),
|
||||
handle_signals=False)
|
||||
|
||||
def setup_service(config: Configuration, database: Database, loot: LootSelector, party: Party) -> web.Application:
|
||||
def setup_service(config: Configuration, database: Database, aggregator: PartyAggregator) -> web.Application:
|
||||
app = web.Application(logger=logging.getLogger('http'))
|
||||
app.on_shutdown.append(on_shutdown)
|
||||
|
||||
@ -62,10 +61,7 @@ def setup_service(config: Configuration, database: Database, loot: LootSelector,
|
||||
app.logger.info('setup database')
|
||||
app['database'] = database
|
||||
|
||||
app.logger.info('setup loot selector')
|
||||
app['loot'] = loot
|
||||
|
||||
app.logger.info('setup party worker')
|
||||
app['party'] = party
|
||||
app.logger.info('setup aggregator')
|
||||
app['aggregator'] = aggregator
|
||||
|
||||
return app
|
||||
|
@ -12,9 +12,7 @@ import logging
|
||||
from ffxivbis.api.web import run_server, setup_service
|
||||
from ffxivbis.core.config import Configuration
|
||||
from ffxivbis.core.database import Database
|
||||
from ffxivbis.core.loot_selector import LootSelector
|
||||
from ffxivbis.core.party import Party
|
||||
from ffxivbis.models.user import User
|
||||
from ffxivbis.core.party_aggregator import PartyAggregator
|
||||
|
||||
|
||||
class Application:
|
||||
@ -29,13 +27,7 @@ class Application:
|
||||
database = loop.run_until_complete(Database.get(self.config))
|
||||
database.migration()
|
||||
|
||||
party = loop.run_until_complete(Party.get(database))
|
||||
aggregator = PartyAggregator(self.config, database)
|
||||
|
||||
admin = User(self.config.get('auth', 'root_username'), self.config.get('auth', 'root_password'), 'admin')
|
||||
loop.run_until_complete(database.insert_user(admin, True))
|
||||
|
||||
priority = self.config.get('settings', 'priority').split()
|
||||
loot_selector = LootSelector(party, priority)
|
||||
|
||||
web = setup_service(self.config, database, loot_selector, party)
|
||||
web = setup_service(self.config, database, aggregator)
|
||||
run_server(web)
|
@ -59,40 +59,43 @@ class Database:
|
||||
async def init(self) -> None:
|
||||
pass
|
||||
|
||||
async def delete_piece(self, player_id: PlayerId, piece: Union[Piece, Upgrade]) -> None:
|
||||
async def delete_piece(self, party_id: str, player_id: PlayerId, piece: Union[Piece, Upgrade]) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def delete_piece_bis(self, player_id: PlayerId, piece: Piece) -> None:
|
||||
async def delete_piece_bis(self, party_id: str, player_id: PlayerId, piece: Piece) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def delete_player(self, player_id: PlayerId) -> None:
|
||||
async def delete_player(self, party_id: str, player_id: PlayerId) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def delete_user(self, username: str) -> None:
|
||||
async def delete_user(self, party_id: str, username: str) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def get_party(self) -> List[Player]:
|
||||
async def get_party(self, party_id: str) -> List[Player]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def get_player(self, player_id: PlayerId) -> Optional[int]:
|
||||
async def get_player(self, party_id: str, player_id: PlayerId) -> Optional[int]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def get_user(self, username: str) -> Optional[User]:
|
||||
async def get_players(self, party_id: str) -> List[int]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def get_users(self) -> List[User]:
|
||||
async def get_user(self, party_id: str, username: str) -> Optional[User]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def insert_piece(self, player_id: PlayerId, piece: Union[Piece, Upgrade]) -> None:
|
||||
async def get_users(self, party_id: str) -> List[User]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def insert_piece_bis(self, player_id: PlayerId, piece: Piece) -> None:
|
||||
async def insert_piece(self, party_id: str, player_id: PlayerId, piece: Union[Piece, Upgrade]) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def insert_player(self, player: Player) -> None:
|
||||
async def insert_piece_bis(self, party_id: str, player_id: PlayerId, piece: Piece) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def insert_user(self, user: User, hashed_password: bool) -> None:
|
||||
async def insert_player(self, party_id: str, player: Player) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def insert_user(self, party_id: str, user: User, hashed_password: bool) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def migration(self) -> None:
|
||||
|
@ -20,8 +20,9 @@ from .database import Database
|
||||
|
||||
class Party:
|
||||
|
||||
def __init__(self, database: Database) -> None:
|
||||
def __init__(self, party_id: str, database: Database) -> None:
|
||||
self.lock = Lock()
|
||||
self.party_id = party_id
|
||||
self.players: Dict[PlayerId, Player] = {}
|
||||
self.database = database
|
||||
|
||||
@ -31,9 +32,9 @@ class Party:
|
||||
return list(self.players.values())
|
||||
|
||||
@classmethod
|
||||
async def get(cls: Type[Party], database: Database) -> Party:
|
||||
obj = Party(database)
|
||||
players = await database.get_party()
|
||||
async def get(cls: Type[Party], party_id: str, database: Database) -> Party:
|
||||
obj = cls(party_id, database)
|
||||
players = await database.get_party(party_id)
|
||||
for player in players:
|
||||
obj.players[player.player_id] = player
|
||||
return obj
|
||||
@ -42,28 +43,28 @@ class Party:
|
||||
with self.lock:
|
||||
player = self.players[player_id]
|
||||
player.link = link
|
||||
await self.database.insert_player(player)
|
||||
await self.database.insert_player(self.party_id, player)
|
||||
|
||||
async def remove_player(self, player_id: PlayerId) -> Optional[Player]:
|
||||
await self.database.delete_player(player_id)
|
||||
await self.database.delete_player(self.party_id, player_id)
|
||||
with self.lock:
|
||||
player = self.players.pop(player_id, None)
|
||||
return player
|
||||
|
||||
async def set_player(self, player: Player) -> PlayerId:
|
||||
player_id = player.player_id
|
||||
await self.database.insert_player(player)
|
||||
await self.database.insert_player(self.party_id, player)
|
||||
with self.lock:
|
||||
self.players[player_id] = player
|
||||
return player_id
|
||||
|
||||
async def set_item(self, player_id: PlayerId, piece: Union[Piece, Upgrade]) -> None:
|
||||
await self.database.insert_piece(player_id, piece)
|
||||
await self.database.insert_piece(self.party_id, player_id, piece)
|
||||
with self.lock:
|
||||
self.players[player_id].loot.append(piece)
|
||||
|
||||
async def remove_item(self, player_id: PlayerId, piece: Union[Piece, Upgrade]) -> None:
|
||||
await self.database.delete_piece(player_id, piece)
|
||||
await self.database.delete_piece(self.party_id, player_id, piece)
|
||||
with self.lock:
|
||||
try:
|
||||
self.players[player_id].loot.remove(piece)
|
||||
@ -71,11 +72,11 @@ class Party:
|
||||
pass
|
||||
|
||||
async def set_item_bis(self, player_id: PlayerId, piece: Piece) -> None:
|
||||
await self.database.insert_piece_bis(player_id, piece)
|
||||
await self.database.insert_piece_bis(self.party_id, player_id, piece)
|
||||
with self.lock:
|
||||
self.players[player_id].bis.set_item(piece)
|
||||
|
||||
async def remove_item_bis(self, player_id: PlayerId, piece: Piece) -> None:
|
||||
await self.database.delete_piece_bis(player_id, piece)
|
||||
await self.database.delete_piece_bis(self.party_id, player_id, piece)
|
||||
with self.lock:
|
||||
self.players[player_id].bis.remove_item(piece)
|
||||
|
26
src/ffxivbis/core/party_aggregator.py
Normal file
26
src/ffxivbis/core/party_aggregator.py
Normal file
@ -0,0 +1,26 @@
|
||||
#
|
||||
# Copyright (c) 2019 Evgeniy Alekseev.
|
||||
#
|
||||
# This file is part of ffxivbis
|
||||
# (see https://github.com/arcan1s/ffxivbis).
|
||||
#
|
||||
# License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
|
||||
#
|
||||
from .config import Configuration
|
||||
from .database import Database
|
||||
from .loot_selector import LootSelector
|
||||
from .party import Party
|
||||
|
||||
|
||||
class PartyAggregator:
|
||||
|
||||
def __init__(self, config: Configuration, database: Database) -> None:
|
||||
self.config = config
|
||||
self.database = database
|
||||
|
||||
async def get_party(self, party_id: str) -> Party:
|
||||
return await Party.get(party_id, self.database)
|
||||
|
||||
async def get_loot_selector(self, party: Party) -> LootSelector:
|
||||
priority = self.config.get('settings', 'priority').split()
|
||||
return LootSelector(party, priority)
|
@ -42,8 +42,8 @@ class PostgresDatabase(Database):
|
||||
self.pool = await asyncpg.create_pool(host=self.host, port=self.port, username=self.username,
|
||||
password=self.password, database=self.database)
|
||||
|
||||
async def delete_piece(self, player_id: PlayerId, piece: Union[Piece, Upgrade]) -> None:
|
||||
player = await self.get_player(player_id)
|
||||
async def delete_piece(self, party_id: str, player_id: PlayerId, piece: Union[Piece, Upgrade]) -> None:
|
||||
player = await self.get_player(party_id, player_id)
|
||||
if player is None:
|
||||
return
|
||||
|
||||
@ -57,8 +57,8 @@ class PostgresDatabase(Database):
|
||||
player, piece.name, getattr(piece, 'is_tome', True)
|
||||
)
|
||||
|
||||
async def delete_piece_bis(self, player_id: PlayerId, piece: Piece) -> None:
|
||||
player = await self.get_player(player_id)
|
||||
async def delete_piece_bis(self, party_id: str, player_id: PlayerId, piece: Piece) -> None:
|
||||
player = await self.get_player(party_id, player_id)
|
||||
if player is None:
|
||||
return
|
||||
|
||||
@ -67,24 +67,29 @@ class PostgresDatabase(Database):
|
||||
'''delete from bis where player_id = $1 and piece = $2''',
|
||||
player, piece.name)
|
||||
|
||||
async def delete_player(self, player_id: PlayerId) -> None:
|
||||
async def delete_player(self, party_id: str, player_id: PlayerId) -> None:
|
||||
async with self.pool.acquire() as conn:
|
||||
await conn.execute('''delete from players where nick = $1 and job = $2''',
|
||||
player_id.nick, player_id.job.name)
|
||||
await conn.execute('''delete from players where nick = $1 and job = $2 and party_id = $3''',
|
||||
player_id.nick, player_id.job.name, party_id)
|
||||
|
||||
async def delete_user(self, username: str) -> None:
|
||||
async def delete_user(self, party_id: str, username: str) -> None:
|
||||
async with self.pool.acquire() as conn:
|
||||
await conn.execute('''delete from users where username = $1''', username)
|
||||
await conn.execute('''delete from users where username = $1 and party_id = $2''',
|
||||
(username, party_id))
|
||||
|
||||
async def get_party(self, party_id: str) -> List[Player]:
|
||||
players = await self.get_players(party_id)
|
||||
if not players:
|
||||
return []
|
||||
|
||||
async def get_party(self) -> List[Player]:
|
||||
async with self.pool.acquire() as conn:
|
||||
rows = await conn.fetch('''select * from bis''')
|
||||
rows = await conn.fetch('''select * from bis where player_id in $1''', players)
|
||||
bis_pieces = [Loot(row['player_id'], Piece.get(row)) for row in rows]
|
||||
|
||||
rows = await conn.fetch('''select * from loot''')
|
||||
rows = await conn.fetch('''select * from loot where player_id in $1''', players)
|
||||
loot_pieces = [Loot(row['player_id'], Piece.get(row)) for row in rows]
|
||||
|
||||
rows = await conn.fetch('''select * from players''')
|
||||
rows = await conn.fetch('''select * from players where party_id = $1''', party_id)
|
||||
party = {
|
||||
row['player_id']: Player(Job[row['job']], row['nick'], BiS(), [], row['bis_link'], row['priority'])
|
||||
for row in rows
|
||||
@ -92,24 +97,30 @@ class PostgresDatabase(Database):
|
||||
|
||||
return self.set_loot(party, bis_pieces, loot_pieces)
|
||||
|
||||
async def get_player(self, player_id: PlayerId) -> Optional[int]:
|
||||
async def get_player(self, party_id: str, player_id: PlayerId) -> Optional[int]:
|
||||
async with self.pool.acquire() as conn:
|
||||
player = await conn.fetchrow('''select player_id from players where nick = $1 and job = $2''',
|
||||
player_id.nick, player_id.job.name)
|
||||
player = await conn.fetchrow('''select player_id from players where nick = $1 and job = $2 and party_id = $3''',
|
||||
player_id.nick, player_id.job.name, party_id)
|
||||
return player['player_id'] if player is not None else None
|
||||
|
||||
async def get_user(self, username: str) -> Optional[User]:
|
||||
async def get_players(self, party_id: str) -> List[int]:
|
||||
async with self.pool.acquire() as conn:
|
||||
user = await conn.fetchrow('''select * from users where username = $1''', username)
|
||||
players = await conn.fetch('''select player_id from players where party_id = $1''', (party_id,))
|
||||
return [player['player_id'] for player in players]
|
||||
|
||||
async def get_user(self, party_id: str, username: str) -> Optional[User]:
|
||||
async with self.pool.acquire() as conn:
|
||||
user = await conn.fetchrow('''select * from users where username = $1 and party_id = $2''',
|
||||
username, party_id)
|
||||
return User(user['username'], user['password'], user['permission']) if user is not None else None
|
||||
|
||||
async def get_users(self) -> List[User]:
|
||||
async def get_users(self, party_id: str) -> List[User]:
|
||||
async with self.pool.acquire() as conn:
|
||||
users = await conn.fetch('''select * from users''')
|
||||
users = await conn.fetch('''select * from users where party_id = $1''', party_id)
|
||||
return [User(user['username'], user['password'], user['permission']) for user in users]
|
||||
|
||||
async def insert_piece(self, player_id: PlayerId, piece: Union[Piece, Upgrade]) -> None:
|
||||
player = await self.get_player(player_id)
|
||||
async def insert_piece(self, party_id: str, player_id: PlayerId, piece: Union[Piece, Upgrade]) -> None:
|
||||
player = await self.get_player(party_id, player_id)
|
||||
if player is None:
|
||||
return
|
||||
|
||||
@ -122,8 +133,8 @@ class PostgresDatabase(Database):
|
||||
Database.now(), piece.name, getattr(piece, 'is_tome', True), player
|
||||
)
|
||||
|
||||
async def insert_piece_bis(self, player_id: PlayerId, piece: Piece) -> None:
|
||||
player = await self.get_player(player_id)
|
||||
async def insert_piece_bis(self, party_id: str, player_id: PlayerId, piece: Piece) -> None:
|
||||
player = await self.get_player(party_id, player_id)
|
||||
if player is None:
|
||||
return
|
||||
|
||||
@ -138,27 +149,27 @@ class PostgresDatabase(Database):
|
||||
Database.now(), piece.name, piece.is_tome, player
|
||||
)
|
||||
|
||||
async def insert_player(self, player: Player) -> None:
|
||||
async def insert_player(self, party_id: str, player: Player) -> None:
|
||||
async with self.pool.acquire() as conn:
|
||||
await conn.execute(
|
||||
'''insert into players
|
||||
(created, nick, job, bis_link, priority)
|
||||
(party_id, created, nick, job, bis_link, priority)
|
||||
values
|
||||
($1, $2, $3, $4, $5)
|
||||
($1, $2, $3, $4, $5, $6)
|
||||
on conflict on constraint players_nick_job_idx do update set
|
||||
created = $1, bis_link = $4, priority = $5''',
|
||||
Database.now(), player.nick, player.job.name, player.link, player.priority
|
||||
Database.now(), player.nick, player.job.name, player.link, player.priority, party_id
|
||||
)
|
||||
|
||||
async def insert_user(self, user: User, hashed_password: bool) -> None:
|
||||
async def insert_user(self, party_id: str, user: User, hashed_password: bool) -> None:
|
||||
password = user.password if hashed_password else md5_crypt.hash(user.password)
|
||||
async with self.pool.acquire() as conn:
|
||||
await conn.execute(
|
||||
'''insert into users
|
||||
(username, password, permission)
|
||||
(party_id, username, password, permission)
|
||||
values
|
||||
($1, $2, $3)
|
||||
($1, $2, $3, $4)
|
||||
on conflict on constraint users_username_idx do update set
|
||||
password = $2, permission = $3''',
|
||||
user.username, password, user.permission
|
||||
party_id, user.username, password, user.permission
|
||||
)
|
@ -31,8 +31,8 @@ class SQLiteDatabase(Database):
|
||||
def connection(self) -> str:
|
||||
return f'sqlite:///{self.database_path}'
|
||||
|
||||
async def delete_piece(self, player_id: PlayerId, piece: Union[Piece, Upgrade]) -> None:
|
||||
player = await self.get_player(player_id)
|
||||
async def delete_piece(self, party_id: str, player_id: PlayerId, piece: Union[Piece, Upgrade]) -> None:
|
||||
player = await self.get_player(party_id, player_id)
|
||||
if player is None:
|
||||
return
|
||||
|
||||
@ -45,8 +45,8 @@ class SQLiteDatabase(Database):
|
||||
)''',
|
||||
(player, piece.name, getattr(piece, 'is_tome', True)))
|
||||
|
||||
async def delete_piece_bis(self, player_id: PlayerId, piece: Piece) -> None:
|
||||
player = await self.get_player(player_id)
|
||||
async def delete_piece_bis(self, party_id: str, player_id: PlayerId, piece: Piece) -> None:
|
||||
player = await self.get_player(party_id, player_id)
|
||||
if player is None:
|
||||
return
|
||||
|
||||
@ -55,26 +55,32 @@ class SQLiteDatabase(Database):
|
||||
'''delete from bis where player_id = ? and piece = ?''',
|
||||
(player, piece.name))
|
||||
|
||||
async def delete_player(self, player_id: PlayerId) -> None:
|
||||
async def delete_player(self, party_id: str, player_id: PlayerId) -> None:
|
||||
async with SQLiteHelper(self.database_path) as cursor:
|
||||
await cursor.execute('''delete from players where nick = ? and job = ?''',
|
||||
(player_id.nick, player_id.job.name))
|
||||
await cursor.execute('''delete from players where nick = ? and job = ? and party_id = ?''',
|
||||
(player_id.nick, player_id.job.name, party_id))
|
||||
|
||||
async def delete_user(self, username: str) -> None:
|
||||
async def delete_user(self, party_id: str, username: str) -> None:
|
||||
async with SQLiteHelper(self.database_path) as cursor:
|
||||
await cursor.execute('''delete from users where username = ?''', (username,))
|
||||
await cursor.execute('''delete from users where username = ? and party_id = ?''',
|
||||
(username, party_id))
|
||||
|
||||
async def get_party(self, party_id: str) -> List[Player]:
|
||||
players = await self.get_players(party_id)
|
||||
if not players:
|
||||
return []
|
||||
placeholder = ', '.join(['?'] * len(players))
|
||||
|
||||
async def get_party(self) -> List[Player]:
|
||||
async with SQLiteHelper(self.database_path) as cursor:
|
||||
await cursor.execute('''select * from bis''')
|
||||
await cursor.execute('''select * from bis where player_id in ({})'''.format(placeholder), players)
|
||||
rows = await cursor.fetchall()
|
||||
bis_pieces = [Loot(row['player_id'], Piece.get(row)) for row in rows]
|
||||
|
||||
await cursor.execute('''select * from loot''')
|
||||
await cursor.execute('''select * from loot where player_id in ({})'''.format(placeholder), players)
|
||||
rows = await cursor.fetchall()
|
||||
loot_pieces = [Loot(row['player_id'], Piece.get(row)) for row in rows]
|
||||
|
||||
await cursor.execute('''select * from players''')
|
||||
await cursor.execute('''select * from players where party_id = ?''', (party_id,))
|
||||
rows = await cursor.fetchall()
|
||||
party = {
|
||||
row['player_id']: Player(Job[row['job']], row['nick'], BiS(), [], row['bis_link'], row['priority'])
|
||||
@ -83,27 +89,34 @@ class SQLiteDatabase(Database):
|
||||
|
||||
return self.set_loot(party, bis_pieces, loot_pieces)
|
||||
|
||||
async def get_player(self, player_id: PlayerId) -> Optional[int]:
|
||||
async def get_player(self, party_id: str, player_id: PlayerId) -> Optional[int]:
|
||||
async with SQLiteHelper(self.database_path) as cursor:
|
||||
await cursor.execute('''select player_id from players where nick = ? and job = ?''',
|
||||
(player_id.nick, player_id.job.name))
|
||||
await cursor.execute('''select player_id from players where nick = ? and job = ? and party_id = ?''',
|
||||
(player_id.nick, player_id.job.name, party_id))
|
||||
player = await cursor.fetchone()
|
||||
return player['player_id'] if player is not None else None
|
||||
|
||||
async def get_user(self, username: str) -> Optional[User]:
|
||||
async def get_players(self, party_id: str) -> List[int]:
|
||||
async with SQLiteHelper(self.database_path) as cursor:
|
||||
await cursor.execute('''select * from users where username = ?''', (username,))
|
||||
await cursor.execute('''select player_id from players where party_id = ?''', (party_id,))
|
||||
players = await cursor.fetchall()
|
||||
return [player['player_id'] for player in players]
|
||||
|
||||
async def get_user(self, party_id: str, username: str) -> Optional[User]:
|
||||
async with SQLiteHelper(self.database_path) as cursor:
|
||||
await cursor.execute('''select * from users where username = ? and party_id = ?''',
|
||||
(username, party_id))
|
||||
user = await cursor.fetchone()
|
||||
return User(user['username'], user['password'], user['permission']) if user is not None else None
|
||||
|
||||
async def get_users(self) -> List[User]:
|
||||
async def get_users(self, party_id: str) -> List[User]:
|
||||
async with SQLiteHelper(self.database_path) as cursor:
|
||||
await cursor.execute('''select * from users''')
|
||||
await cursor.execute('''select * from users where party_id = ?''', (party_id,))
|
||||
users = await cursor.fetchall()
|
||||
return [User(user['username'], user['password'], user['permission']) for user in users]
|
||||
|
||||
async def insert_piece(self, player_id: PlayerId, piece: Union[Piece, Upgrade]) -> None:
|
||||
player = await self.get_player(player_id)
|
||||
async def insert_piece(self, party_id: str, player_id: PlayerId, piece: Union[Piece, Upgrade]) -> None:
|
||||
player = await self.get_player(party_id, player_id)
|
||||
if player is None:
|
||||
return
|
||||
|
||||
@ -116,8 +129,8 @@ class SQLiteDatabase(Database):
|
||||
(Database.now(), piece.name, getattr(piece, 'is_tome', True), player)
|
||||
)
|
||||
|
||||
async def insert_piece_bis(self, player_id: PlayerId, piece: Piece) -> None:
|
||||
player = await self.get_player(player_id)
|
||||
async def insert_piece_bis(self, party_id: str, player_id: PlayerId, piece: Piece) -> None:
|
||||
player = await self.get_player(party_id, player_id)
|
||||
if player is None:
|
||||
return
|
||||
|
||||
@ -130,23 +143,23 @@ class SQLiteDatabase(Database):
|
||||
(Database.now(), piece.name, piece.is_tome, player)
|
||||
)
|
||||
|
||||
async def insert_player(self, player: Player) -> None:
|
||||
async def insert_player(self, party_id: str, player: Player) -> None:
|
||||
async with SQLiteHelper(self.database_path) as cursor:
|
||||
await cursor.execute(
|
||||
'''replace into players
|
||||
(created, nick, job, bis_link, priority)
|
||||
(party_id, created, nick, job, bis_link, priority)
|
||||
values
|
||||
(?, ?, ?, ?, ?)''',
|
||||
(Database.now(), player.nick, player.job.name, player.link, player.priority)
|
||||
(?, ?, ?, ?, ?, ?)''',
|
||||
(party_id, Database.now(), player.nick, player.job.name, player.link, player.priority)
|
||||
)
|
||||
|
||||
async def insert_user(self, user: User, hashed_password: bool) -> None:
|
||||
async def insert_user(self, party_id: str, user: User, hashed_password: bool) -> None:
|
||||
password = user.password if hashed_password else md5_crypt.hash(user.password)
|
||||
async with SQLiteHelper(self.database_path) as cursor:
|
||||
await cursor.execute(
|
||||
'''replace into users
|
||||
(username, password, permission)
|
||||
(party_id, username, password, permission)
|
||||
values
|
||||
(?, ?, ?)''',
|
||||
(user.username, password, user.permission)
|
||||
(?, ?, ?, ?)''',
|
||||
(party_id, user.username, password, user.permission)
|
||||
)
|
Loading…
Reference in New Issue
Block a user