mirror of
https://github.com/arcan1s/ffxivbis.git
synced 2025-04-25 09:47:18 +00:00
add loot interfaces
This commit is contained in:
parent
9bd51d9267
commit
2ea8fed183
@ -13,6 +13,8 @@ from service.api.views.api.loot import LootView
|
||||
from service.api.views.api.player import PlayerView
|
||||
from service.api.views.html.bis import BiSHtmlView
|
||||
from service.api.views.html.index import IndexHtmlView
|
||||
from service.api.views.html.loot import LootHtmlView
|
||||
from service.api.views.html.loot_suggest import LootSuggestHtmlView
|
||||
from service.api.views.html.player import PlayerHtmlView
|
||||
|
||||
|
||||
@ -37,3 +39,9 @@ def setup_routes(app: Application) -> None:
|
||||
|
||||
app.router.add_get('/bis', BiSHtmlView)
|
||||
app.router.add_post('/bis', BiSHtmlView)
|
||||
|
||||
app.router.add_get('/loot', LootHtmlView)
|
||||
app.router.add_post('/loot', LootHtmlView)
|
||||
|
||||
app.router.add_get('/suggest', LootSuggestHtmlView)
|
||||
app.router.add_post('/suggest', LootSuggestHtmlView)
|
||||
|
@ -7,10 +7,11 @@
|
||||
# License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
|
||||
#
|
||||
from aiohttp.web import View
|
||||
from typing import List, Optional
|
||||
from typing import List, Optional, Union
|
||||
|
||||
from service.models.piece import Piece
|
||||
from service.models.player import PlayerId, PlayerIdWithCounters
|
||||
from service.models.upgrade import Upgrade
|
||||
|
||||
|
||||
class LootBaseView(View):
|
||||
@ -34,7 +35,7 @@ class LootBaseView(View):
|
||||
return self.loot_remove(player_id, piece)
|
||||
return None
|
||||
|
||||
def loot_put(self, piece: Piece) -> List[PlayerIdWithCounters]:
|
||||
def loot_put(self, piece: Union[Piece, Upgrade]) -> List[PlayerIdWithCounters]:
|
||||
return self.request.app['loot'].suggest(piece)
|
||||
|
||||
def loot_remove(self, player_id: PlayerId, piece: Piece) -> Piece:
|
||||
|
@ -10,11 +10,10 @@ from aiohttp.web import HTTPFound, Response
|
||||
from aiohttp_jinja2 import template
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from service.models.job import Job
|
||||
from service.models.piece import Piece
|
||||
from service.models.player import PlayerId
|
||||
from service.models.player import Player, PlayerId
|
||||
|
||||
from service.api.utils import wrap_exception, wrap_invalid_param, wrap_json
|
||||
from service.api.utils import wrap_exception, wrap_invalid_param
|
||||
from service.api.views.common.bis_base import BiSBaseView
|
||||
from service.api.views.common.player_base import PlayerBaseView
|
||||
|
||||
@ -23,8 +22,9 @@ class BiSHtmlView(BiSBaseView, PlayerBaseView):
|
||||
|
||||
@template('bis.jinja2')
|
||||
async def get(self) -> Dict[str, Any]:
|
||||
items: List[Dict[str, str]] = []
|
||||
error = None
|
||||
items: List[Dict[str, str]] = []
|
||||
players: List[Player] = []
|
||||
|
||||
try:
|
||||
players = self.player_get(None)
|
||||
@ -43,8 +43,9 @@ class BiSHtmlView(BiSBaseView, PlayerBaseView):
|
||||
error = repr(e)
|
||||
|
||||
return {
|
||||
'items': items,
|
||||
'pieces': Piece.available(),
|
||||
'players': items,
|
||||
'players': [player.player_id.pretty_name for player in players],
|
||||
'request_error': error
|
||||
}
|
||||
|
||||
@ -57,21 +58,21 @@ class BiSHtmlView(BiSBaseView, PlayerBaseView):
|
||||
|
||||
try:
|
||||
method = data.get('method')
|
||||
player_id = PlayerId.from_pretty_name(data.get('player'))
|
||||
player_id = PlayerId.from_pretty_name(data.get('player')) # type: ignore
|
||||
|
||||
if method == 'post':
|
||||
required = ['action', 'piece']
|
||||
if any(param not in data for param in required):
|
||||
return wrap_invalid_param(required, data)
|
||||
self.bis_post(data.get('action'), player_id,
|
||||
Piece.get({'piece': data.get('piece'), 'is_tome': data.get('is_tome', False)}))
|
||||
self.bis_post(data.get('action'), player_id, # type: ignore
|
||||
Piece.get({'piece': data.get('piece'), 'is_tome': data.get('is_tome', False)})) # type: ignore
|
||||
|
||||
elif method == 'put':
|
||||
required = ['bis']
|
||||
if any(param not in data for param in required):
|
||||
return wrap_invalid_param(required, data)
|
||||
|
||||
self.bis_put(player_id, data.get('bis'))
|
||||
self.bis_put(player_id, data.get('bis')) # type: ignore
|
||||
|
||||
except Exception as e:
|
||||
self.request.app.logger.exception('could not manage bis')
|
||||
|
68
src/service/api/views/html/loot.py
Normal file
68
src/service/api/views/html/loot.py
Normal file
@ -0,0 +1,68 @@
|
||||
#
|
||||
# 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 aiohttp.web import HTTPFound, Response
|
||||
from aiohttp_jinja2 import template
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from service.models.piece import Piece
|
||||
from service.models.player import Player, PlayerId
|
||||
|
||||
from service.api.utils import wrap_exception, wrap_invalid_param
|
||||
from service.api.views.common.loot_base import LootBaseView
|
||||
from service.api.views.common.player_base import PlayerBaseView
|
||||
|
||||
|
||||
class LootHtmlView(LootBaseView, PlayerBaseView):
|
||||
|
||||
@template('loot.jinja2')
|
||||
async def get(self) -> Dict[str, Any]:
|
||||
error = None
|
||||
items: List[Dict[str, str]] = []
|
||||
players: List[Player] = []
|
||||
|
||||
try:
|
||||
players = self.player_get(None)
|
||||
items = [
|
||||
{
|
||||
'player': player.player_id.pretty_name,
|
||||
'piece': piece.name,
|
||||
'is_tome': 'yes' if piece.is_tome else 'no' # type: ignore
|
||||
}
|
||||
for player in players
|
||||
for piece in player.loot
|
||||
]
|
||||
|
||||
except Exception as e:
|
||||
self.request.app.logger.exception('could not get loot')
|
||||
error = repr(e)
|
||||
|
||||
return {
|
||||
'items': items,
|
||||
'pieces': Piece.available(),
|
||||
'players': [player.player_id.pretty_name for player in players],
|
||||
'request_error': error
|
||||
}
|
||||
|
||||
async def post(self) -> Response:
|
||||
data = await self.request.post()
|
||||
|
||||
required = ['action', 'piece', 'player']
|
||||
if any(param not in data for param in required):
|
||||
return wrap_invalid_param(required, data)
|
||||
|
||||
try:
|
||||
player_id = PlayerId.from_pretty_name(data.get('player')) # type: ignore
|
||||
self.loot_post(data.get('action'), player_id, # type: ignore
|
||||
Piece.get({'piece': data.get('piece'), 'is_tome': data.get('is_tome', False)})) # type: ignore
|
||||
|
||||
except Exception as e:
|
||||
self.request.app.logger.exception('could not manage loot')
|
||||
return wrap_exception(e, data)
|
||||
|
||||
return HTTPFound(self.request.url)
|
60
src/service/api/views/html/loot_suggest.py
Normal file
60
src/service/api/views/html/loot_suggest.py
Normal file
@ -0,0 +1,60 @@
|
||||
#
|
||||
# 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 aiohttp.web import Response
|
||||
from aiohttp_jinja2 import template
|
||||
from typing import Any, Dict, List, Union
|
||||
|
||||
from service.models.piece import Piece
|
||||
from service.models.player import Player, PlayerIdWithCounters
|
||||
|
||||
from service.api.utils import wrap_invalid_param
|
||||
from service.api.views.common.loot_base import LootBaseView
|
||||
from service.api.views.common.player_base import PlayerBaseView
|
||||
|
||||
|
||||
class LootSuggestHtmlView(LootBaseView, PlayerBaseView):
|
||||
|
||||
@template('loot_suggest.jinja2')
|
||||
async def get(self) -> Dict[str, Any]:
|
||||
return {
|
||||
'pieces': Piece.available(),
|
||||
'players': [player.player_id.pretty_name for player in self.player_get(None)],
|
||||
}
|
||||
|
||||
@template('loot_suggest.jinja2')
|
||||
async def post(self) -> Union[Dict[str, Any], Response]:
|
||||
data = await self.request.post()
|
||||
error = None
|
||||
players: List[PlayerIdWithCounters] = []
|
||||
|
||||
required = ['piece']
|
||||
if any(param not in data for param in required):
|
||||
return wrap_invalid_param(required, data)
|
||||
|
||||
try:
|
||||
piece = Piece.get({'piece': data.get('piece'), 'is_tome': data.get('is_tome', False)})
|
||||
players = self.loot_put(piece)
|
||||
|
||||
except Exception as e:
|
||||
self.request.app.logger.exception('could not manage loot')
|
||||
error = repr(e)
|
||||
|
||||
return {
|
||||
'pieces': Piece.available(),
|
||||
'players': [player.player_id.pretty_name for player in self.player_get(None)],
|
||||
'suggest': [
|
||||
{
|
||||
'player': player.pretty_name,
|
||||
'loot_count_bis': player.loot_count_bis,
|
||||
'loot_count': player.loot_count,
|
||||
}
|
||||
for player in players
|
||||
],
|
||||
'request_error': error
|
||||
}
|
@ -57,7 +57,7 @@ class PlayerHtmlView(PlayerBaseView):
|
||||
action = data.get('action')
|
||||
priority = data.get('priority', 0)
|
||||
link = data.get('bis', None)
|
||||
self.player_post(action, Job[data['job'].upper()], data['nick'], link, priority)
|
||||
self.player_post(action, Job[data['job'].upper()], data['nick'], link, priority) # type: ignore
|
||||
|
||||
except Exception as e:
|
||||
self.request.app.logger.exception('could not manage players')
|
||||
|
@ -29,8 +29,10 @@ class PlayerId:
|
||||
return '{} ({})'.format(self.nick, self.job.name)
|
||||
|
||||
@classmethod
|
||||
def from_pretty_name(cls: Type[PlayerId], value: str) -> PlayerId:
|
||||
def from_pretty_name(cls: Type[PlayerId], value: str) -> Optional[PlayerId]:
|
||||
matches = re.search('^(?P<nick>.*) \((?P<job>[A-Z]+)\)$', value)
|
||||
if matches is None:
|
||||
return None
|
||||
return PlayerId(Job[matches.group('job')], matches.group('nick'))
|
||||
|
||||
def __hash__(self) -> int:
|
||||
|
@ -13,7 +13,7 @@
|
||||
<form action="/bis" method="post">
|
||||
<select name="player" id="player" title="player">
|
||||
{% for player in players %}
|
||||
<option>{{ player.player|e }}</option>
|
||||
<option>{{ player|e }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<select name="piece" id="piece" title="piece">
|
||||
@ -29,7 +29,7 @@
|
||||
<form action="/bis" method="post">
|
||||
<select name="player" id="player" title="player">
|
||||
{% for player in players %}
|
||||
<option>{{ player.player|e }}</option>
|
||||
<option>{{ player|e }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input name="bis" id="bis" placeholder="player bis link" title="bis" type="text"/>
|
||||
@ -45,11 +45,11 @@
|
||||
<th></th>
|
||||
</tr>
|
||||
|
||||
{% for player in players %}
|
||||
{% for item in items %}
|
||||
<tr>
|
||||
<td class="include_search">{{ player.player|e }}</td>
|
||||
<td class="include_search">{{ player.piece|e }}</td>
|
||||
<td>{{ player.is_tome|e }}</td>
|
||||
<td class="include_search">{{ item.player|e }}</td>
|
||||
<td class="include_search">{{ item.piece|e }}</td>
|
||||
<td>{{ item.is_tome|e }}</td>
|
||||
<td>
|
||||
<form action="/bis" method="post">
|
||||
<input name="action" id="action" type="hidden" value="remove"/>
|
||||
|
@ -8,6 +8,7 @@
|
||||
<a href="/party" title="party"><h2>party</h2></a>
|
||||
<a href="/bis" title="bis management"><h2>bis</h2></a>
|
||||
<a href="/loot" title="loot management"><h2>loot</h2></a>
|
||||
<a href="/suggest" title="suggest loot"><h2>suggest</h2></a>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||
|
56
templates/loot.jinja2
Normal file
56
templates/loot.jinja2
Normal file
@ -0,0 +1,56 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Loot</title>
|
||||
|
||||
{% include "style.jinja2" %}
|
||||
</head>
|
||||
<body>
|
||||
<h2>Loot</h2>
|
||||
|
||||
{% include "error.jinja2" %}
|
||||
{% include "search_line.jinja2" %}
|
||||
|
||||
<form action="/loot" method="post">
|
||||
<select name="player" id="player" title="player">
|
||||
{% for player in players %}
|
||||
<option>{{ player|e }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<select name="piece" id="piece" title="piece">
|
||||
{% for piece in pieces %}
|
||||
<option>{{ piece|e }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input name="is_tome" id="is_tome" title="is tome" type="checkbox"/>
|
||||
<input name="action" id="action" type="hidden" value="add"/>
|
||||
<button>add</button>
|
||||
</form>
|
||||
|
||||
<table id="result">
|
||||
<tr>
|
||||
<th>player</th>
|
||||
<th>piece</th>
|
||||
<th>is_tome</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
||||
{% for item in items %}
|
||||
<tr>
|
||||
<td class="include_search">{{ item.player|e }}</td>
|
||||
<td class="include_search">{{ item.piece|e }}</td>
|
||||
<td>{{ item.is_tome|e }}</td>
|
||||
<td>
|
||||
<form action="/loot" method="post">
|
||||
<input name="action" id="action" type="hidden" value="remove"/>
|
||||
<button>remove</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% include "export_to_csv.jinja2" %}
|
||||
{% include "root.jinja2" %}
|
||||
{% include "search.jinja2" %}
|
||||
</body>
|
||||
</html>
|
48
templates/loot_suggest.jinja2
Normal file
48
templates/loot_suggest.jinja2
Normal file
@ -0,0 +1,48 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Suggest loot</title>
|
||||
|
||||
{% include "style.jinja2" %}
|
||||
</head>
|
||||
<body>
|
||||
<h2>suggest loot</h2>
|
||||
|
||||
{% include "error.jinja2" %}
|
||||
{% include "search_line.jinja2" %}
|
||||
|
||||
<form action="/suggest" method="post">
|
||||
<select name="player" id="player" title="player">
|
||||
{% for player in players %}
|
||||
<option>{{ player|e }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<select name="piece" id="piece" title="piece">
|
||||
{% for piece in pieces %}
|
||||
<option>{{ piece|e }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input name="is_tome" id="is_tome" title="is tome" type="checkbox"/>
|
||||
<button>suggest</button>
|
||||
</form>
|
||||
|
||||
<table id="result">
|
||||
<tr>
|
||||
<th>player</th>
|
||||
<th>bis pieces looted</th>
|
||||
<th>total pieces looted</th>
|
||||
</tr>
|
||||
|
||||
{% for player in suggest %}
|
||||
<tr>
|
||||
<td class="include_search">{{ player.player|e }}</td>
|
||||
<td>{{ player.loot_count_bis|e }}</td>
|
||||
<td>{{ player.loot_count|e }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% include "export_to_csv.jinja2" %}
|
||||
{% include "root.jinja2" %}
|
||||
{% include "search.jinja2" %}
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user