mirror of
https://github.com/arcan1s/ffxivbis.git
synced 2025-04-25 01:37:17 +00:00
complete swagger
This commit is contained in:
parent
c83f36f40b
commit
80ea82904b
104
README.md
104
README.md
@ -2,104 +2,30 @@
|
||||
|
||||
Service which allows to manage savage loot distribution easy.
|
||||
|
||||
## REST API
|
||||
## Installation and usage
|
||||
|
||||
### Party API
|
||||
This service requires python >= 3.7. For other dependencies see `setup.py`.
|
||||
|
||||
* `GET /api/v1/party`
|
||||
|
||||
Get party list. Parameters:
|
||||
|
||||
* `nick`: player full nickname to filter, string, optional.
|
||||
|
||||
* `POST /api/v1/party`
|
||||
In general installation process looks like:
|
||||
|
||||
Add or remove party member. Parameters:
|
||||
|
||||
* `action`: action to do, string, required. One of `add`, `remove`.
|
||||
* `job`: player job name, string, required.
|
||||
* `nick`: player nickname, string, required.
|
||||
* `link`: link to ariyala set to parse BiS, string, optional.
|
||||
|
||||
### BiS API
|
||||
```bash
|
||||
python setup.py build
|
||||
python setup.py test # if you want to run tests
|
||||
```
|
||||
|
||||
* `GET /api/v1/party/bis`
|
||||
Service can be run from `src` directory by using command:
|
||||
|
||||
Get party/player BiS. Parameters:
|
||||
|
||||
* `nick`: player full nickname to filter, string, optional.
|
||||
|
||||
* `POST /api/v1/party/bis`
|
||||
```bash
|
||||
python -m service.application.application
|
||||
```
|
||||
|
||||
Add or remove item to/from BiS. Parameters:
|
||||
|
||||
* `action`: action to do, string, required. One of `add`, `remove`.
|
||||
* `job`: player job name, string, required.
|
||||
* `nick`: player nickname, string, required.
|
||||
* `is_tome`: is item tome gear or not, bool, required.
|
||||
* `piece`: item name, string, required.
|
||||
|
||||
* `PUT /api/v1/party/bis`
|
||||
To see all available options type `--help`.
|
||||
|
||||
Create BiS from ariyala link. Parameters:
|
||||
|
||||
* `job`: player job name, string, required.
|
||||
* `nick`: player nickname, string, required.
|
||||
* `link`: link to ariyala set to parse BiS, string, required.
|
||||
|
||||
### Loot API
|
||||
## Web service
|
||||
|
||||
* `GET /api/v1/party/loot`
|
||||
|
||||
Get party/player loot. Parameters:
|
||||
|
||||
* `nick`: player full nickname to filter, string, optional.
|
||||
|
||||
* `POST /api/v1/party/loot`
|
||||
|
||||
Add or remove item to/from loot list. Parameters:
|
||||
|
||||
* `action`: action to do, string, required. One of `add`, `remove`.
|
||||
* `job`: player job name, string, required.
|
||||
* `nick`: player nickname, string, required.
|
||||
* `is_tome`: is item tome gear or not, bool, required.
|
||||
* `piece`: item name, string, required.
|
||||
|
||||
* `PUT /api/v1/party/loot`
|
||||
|
||||
Suggest players to get loot. Parameters:
|
||||
|
||||
* `is_tome`: is item tome gear or not, bool, required.
|
||||
* `piece`: item name, string, required.
|
||||
|
||||
|
||||
### Users API
|
||||
|
||||
* `DELETE /api/v1/login/{username}`
|
||||
|
||||
Delete user with specified username. Parameters:
|
||||
|
||||
* `username`: username to remove, required.
|
||||
|
||||
* `POST /api/v1/login`
|
||||
|
||||
Login with credentials. Parameters:
|
||||
|
||||
* `username`: username to login, string, required.
|
||||
* `password`: password to login, string, required.
|
||||
|
||||
* `PUT /api/v1/login`
|
||||
|
||||
Create new user. Parameters:
|
||||
|
||||
* `username`: username to login, string, required.
|
||||
* `password`: password to login, string,
|
||||
* `permission`: user permission, one of `get`, `post`, optional, default `get`.
|
||||
|
||||
* `POST /api/v1/logout`
|
||||
|
||||
Logout.
|
||||
REST API documentation is available at `http://0.0.0.0:8000/api-docs`. HTML representation is available at `http://0.0.0.0:8000`.
|
||||
|
||||
*Note*: host and port depend on configuration settings.
|
||||
|
||||
## Configuration
|
||||
|
||||
|
@ -11,13 +11,15 @@ from apispec import APISpec
|
||||
|
||||
from service.core.version import __version__
|
||||
from service.models.action import Action
|
||||
from service.models.bis import BiS
|
||||
from service.models.bis import BiS, BiSLink
|
||||
from service.models.error import Error
|
||||
from service.models.job import Job
|
||||
from service.models.loot import Loot
|
||||
from service.models.piece import Piece
|
||||
from service.models.player import Player, PlayerId
|
||||
from service.models.player import Player, PlayerId, PlayerIdWithCounters
|
||||
from service.models.player_edit import PlayerEdit
|
||||
from service.models.upgrade import Upgrade
|
||||
from service.models.user import User
|
||||
|
||||
|
||||
def get_spec(app: Application) -> APISpec:
|
||||
@ -45,13 +47,17 @@ def get_spec(app: Application) -> APISpec:
|
||||
# components
|
||||
spec.components.schema(Action.model_name(), Action.model_spec())
|
||||
spec.components.schema(BiS.model_name(), BiS.model_spec())
|
||||
spec.components.schema(BiSLink.model_name(), BiSLink.model_spec())
|
||||
spec.components.schema(Error.model_name(), Error.model_spec())
|
||||
spec.components.schema(Job.model_name(), Job.model_spec())
|
||||
spec.components.schema(Loot.model_name(), Loot.model_spec())
|
||||
spec.components.schema(Piece.model_name(), Piece.model_spec())
|
||||
spec.components.schema(Player.model_name(), Player.model_spec())
|
||||
spec.components.schema(PlayerEdit.model_name(), PlayerEdit.model_spec())
|
||||
spec.components.schema(PlayerId.model_name(), PlayerId.model_spec())
|
||||
spec.components.schema(PlayerIdWithCounters.model_name(), PlayerIdWithCounters.model_spec())
|
||||
spec.components.schema(Upgrade.model_name(), Upgrade.model_spec())
|
||||
spec.components.schema(User.model_name(), User.model_spec())
|
||||
|
||||
# default responses
|
||||
spec.components.response('BadRequest', dict(
|
||||
|
@ -7,6 +7,7 @@
|
||||
# License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
|
||||
#
|
||||
from aiohttp.web import Response
|
||||
from typing import Any, Dict, List, Optional, Type
|
||||
|
||||
from service.models.job import Job
|
||||
from service.models.piece import Piece
|
||||
@ -15,8 +16,92 @@ from service.models.player import PlayerId
|
||||
from service.api.utils import wrap_exception, wrap_invalid_param, wrap_json
|
||||
from service.api.views.common.bis_base import BiSBaseView
|
||||
|
||||
from .openapi import OpenApi
|
||||
|
||||
class BiSView(BiSBaseView):
|
||||
|
||||
class BiSView(BiSBaseView, OpenApi):
|
||||
|
||||
@classmethod
|
||||
def endpoint_get_description(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'Get party players BiS items'
|
||||
|
||||
@classmethod
|
||||
def endpoint_get_parameters(cls: Type[OpenApi]) -> List[Dict[str, Any]]:
|
||||
return [
|
||||
{
|
||||
'name': 'nick',
|
||||
'in': 'query',
|
||||
'description': 'player nick name to filter',
|
||||
'required': False,
|
||||
'type': 'string'
|
||||
}
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def endpoint_get_responses(cls: Type[OpenApi]) -> Dict[str, Any]:
|
||||
return {
|
||||
'200': {'content': {'application/json': { 'schema': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'allOf': [{'$ref': cls.model_ref('Piece')}]
|
||||
}}}}}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def endpoint_get_summary(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'get party BiS items'
|
||||
|
||||
@classmethod
|
||||
def endpoint_get_tags(cls: Type[OpenApi]) -> List[str]:
|
||||
return ['BiS']
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_description(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'Add new item to player BiS or remove existing'
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_request_body(cls: Type[OpenApi], content_type: str) -> List[str]:
|
||||
return ['Piece', 'PlayerEdit']
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_responses(cls: Type[OpenApi]) -> Dict[str, Any]:
|
||||
return {
|
||||
'200': {'content': {'application/json': {'schema': {'$ref': cls.model_ref('Loot')}}}}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_summary(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'edit BiS'
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_tags(cls: Type[OpenApi]) -> List[str]:
|
||||
return ['BiS']
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_consumes(cls: Type[OpenApi]) -> List[str]:
|
||||
return ['application/json']
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_description(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'Generate new BiS set'
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_request_body(cls: Type[OpenApi], content_type: str) -> List[str]:
|
||||
return ['BiSLink']
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_responses(cls: Type[OpenApi]) -> Dict[str, Any]:
|
||||
return {
|
||||
'200': {'content': {'application/json': {'schema': {'$ref': cls.model_ref('BiS')}}}}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_summary(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'update BiS'
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_tags(cls: Type[OpenApi]) -> List[str]:
|
||||
return ['BiS']
|
||||
|
||||
async def get(self) -> Response:
|
||||
try:
|
||||
@ -34,7 +119,7 @@ class BiSView(BiSBaseView):
|
||||
except Exception:
|
||||
data = dict(await self.request.post())
|
||||
|
||||
required = ['action', 'is_tome', 'job', 'nick', 'piece']
|
||||
required = ['action', 'is_tome', 'job', 'name', 'nick']
|
||||
if any(param not in data for param in required):
|
||||
return wrap_invalid_param(required, data)
|
||||
|
||||
@ -65,10 +150,10 @@ class BiSView(BiSBaseView):
|
||||
|
||||
try:
|
||||
player_id = PlayerId(Job[data['job']], data['nick'])
|
||||
link = await self.bis_put(player_id, data['link'])
|
||||
bis = await self.bis_put(player_id, data['link'])
|
||||
|
||||
except Exception as e:
|
||||
self.request.app.logger.exception('could not parse bis')
|
||||
return wrap_exception(e, data)
|
||||
|
||||
return wrap_json({'link': link})
|
||||
return wrap_json(bis)
|
@ -7,12 +7,89 @@
|
||||
# License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
|
||||
#
|
||||
from aiohttp.web import Response
|
||||
from typing import Any, Dict, List, Optional, Type
|
||||
|
||||
from service.api.utils import wrap_exception, wrap_invalid_param, wrap_json
|
||||
from service.api.views.common.login_base import LoginBaseView
|
||||
|
||||
from .openapi import OpenApi
|
||||
|
||||
class LoginView(LoginBaseView):
|
||||
|
||||
class LoginView(LoginBaseView, OpenApi):
|
||||
|
||||
@classmethod
|
||||
def endpoint_delete_description(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'Delete registered user'
|
||||
|
||||
@classmethod
|
||||
def endpoint_delete_parameters(cls: Type[OpenApi]) -> List[Dict[str, Any]]:
|
||||
return [
|
||||
{
|
||||
'name': 'username',
|
||||
'in': 'path',
|
||||
'description': 'username to remove',
|
||||
'required': True,
|
||||
'type': 'string'
|
||||
}
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def endpoint_delete_responses(cls: Type[OpenApi]) -> Dict[str, Any]:
|
||||
return {
|
||||
'200': {'content': {'application/json': {'type': 'object'}}}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def endpoint_delete_summary(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'delete user'
|
||||
|
||||
@classmethod
|
||||
def endpoint_delete_tags(cls: Type[OpenApi]) -> List[str]:
|
||||
return ['users']
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_description(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'Login as user'
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_request_body(cls: Type[OpenApi], content_type: str) -> List[str]:
|
||||
return ['User']
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_responses(cls: Type[OpenApi]) -> Dict[str, Any]:
|
||||
return {
|
||||
'200': {'content': {'application/json': {'type': 'object'}}}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_summary(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'login'
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_tags(cls: Type[OpenApi]) -> List[str]:
|
||||
return ['users']
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_description(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'Create new user'
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_request_body(cls: Type[OpenApi], content_type: str) -> List[str]:
|
||||
return ['User']
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_responses(cls: Type[OpenApi]) -> Dict[str, Any]:
|
||||
return {
|
||||
'200': {'content': {'application/json': {'type': 'object'}}}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_summary(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'create user'
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_tags(cls: Type[OpenApi]) -> List[str]:
|
||||
return ['users']
|
||||
|
||||
async def delete(self) -> Response:
|
||||
username = self.request.match_info['username']
|
||||
|
@ -4,12 +4,37 @@
|
||||
# License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
|
||||
#
|
||||
from aiohttp.web import Response
|
||||
from typing import Any, Dict, List, Optional, Type
|
||||
|
||||
from service.api.utils import wrap_exception, wrap_json
|
||||
from service.api.views.common.login_base import LoginBaseView
|
||||
|
||||
from .openapi import OpenApi
|
||||
|
||||
class LogoutView(LoginBaseView):
|
||||
|
||||
class LogoutView(LoginBaseView, OpenApi):
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_description(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'Logout'
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_request_body(cls: Type[OpenApi], content_type: str) -> List[str]:
|
||||
return []
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_responses(cls: Type[OpenApi]) -> Dict[str, Any]:
|
||||
return {
|
||||
'200': {'content': {'application/json': {'type': 'object'}}}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_summary(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'logout'
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_tags(cls: Type[OpenApi]) -> List[str]:
|
||||
return ['users']
|
||||
|
||||
async def post(self) -> Response:
|
||||
try:
|
||||
|
@ -7,6 +7,7 @@
|
||||
# License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
|
||||
#
|
||||
from aiohttp.web import Response
|
||||
from typing import Any, Dict, List, Optional, Type
|
||||
|
||||
from service.models.job import Job
|
||||
from service.models.piece import Piece
|
||||
@ -15,8 +16,92 @@ from service.models.player import PlayerId
|
||||
from service.api.utils import wrap_exception, wrap_invalid_param, wrap_json
|
||||
from service.api.views.common.loot_base import LootBaseView
|
||||
|
||||
from .openapi import OpenApi
|
||||
|
||||
class LootView(LootBaseView):
|
||||
|
||||
class LootView(LootBaseView, OpenApi):
|
||||
|
||||
@classmethod
|
||||
def endpoint_get_description(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'Get party players loot'
|
||||
|
||||
@classmethod
|
||||
def endpoint_get_parameters(cls: Type[OpenApi]) -> List[Dict[str, Any]]:
|
||||
return [
|
||||
{
|
||||
'name': 'nick',
|
||||
'in': 'query',
|
||||
'description': 'player nick name to filter',
|
||||
'required': False,
|
||||
'type': 'string'
|
||||
}
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def endpoint_get_responses(cls: Type[OpenApi]) -> Dict[str, Any]:
|
||||
return {
|
||||
'200': {'content': {'application/json': {'schema': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'allOf': [{'$ref': cls.model_ref('Piece')}]
|
||||
}}}}}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def endpoint_get_summary(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'get party loot'
|
||||
|
||||
@classmethod
|
||||
def endpoint_get_tags(cls: Type[OpenApi]) -> List[str]:
|
||||
return ['loot']
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_description(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'Add new loot item or remove existing'
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_request_body(cls: Type[OpenApi], content_type: str) -> List[str]:
|
||||
return ['Piece', 'PlayerEdit']
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_responses(cls: Type[OpenApi]) -> Dict[str, Any]:
|
||||
return {
|
||||
'200': {'content': {'application/json': {'schema': {'$ref': cls.model_ref('Loot')}}}}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_summary(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'edit loot'
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_tags(cls: Type[OpenApi]) -> List[str]:
|
||||
return ['loot']
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_description(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'Suggest loot to party member'
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_request_body(cls: Type[OpenApi], content_type: str) -> List[str]:
|
||||
return ['Piece']
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_responses(cls: Type[OpenApi]) -> Dict[str, Any]:
|
||||
return {
|
||||
'200': {'content': {'application/json': {'schema': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'allOf': [{'$ref': cls.model_ref('PlayerIdWithCounters')}]
|
||||
}}}}}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_summary(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return 'suggest loot'
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_tags(cls: Type[OpenApi]) -> List[str]:
|
||||
return ['loot']
|
||||
|
||||
async def get(self) -> Response:
|
||||
try:
|
||||
@ -34,7 +119,7 @@ class LootView(LootBaseView):
|
||||
except Exception:
|
||||
data = dict(await self.request.post())
|
||||
|
||||
required = ['action', 'is_tome', 'job', 'nick', 'piece']
|
||||
required = ['action', 'is_tome', 'job', 'name', 'nick']
|
||||
if any(param not in data for param in required):
|
||||
return wrap_invalid_param(required, data)
|
||||
|
||||
@ -59,7 +144,7 @@ class LootView(LootBaseView):
|
||||
except Exception:
|
||||
data = dict(await self.request.post())
|
||||
|
||||
required = ['is_tome', 'piece']
|
||||
required = ['is_tome', 'name']
|
||||
if any(param not in data for param in required):
|
||||
return wrap_invalid_param(required, data)
|
||||
|
||||
|
@ -16,9 +16,38 @@ from service.models.serializable import Serializable
|
||||
class OpenApi(Serializable):
|
||||
|
||||
@classmethod
|
||||
def endpoint_delete_spec(cls: Type[OpenApi]) -> Dict[str, Any]:
|
||||
def endpoint_delete_description(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def endpoint_delete_parameters(cls: Type[OpenApi]) -> List[Dict[str, Any]]:
|
||||
return []
|
||||
|
||||
@classmethod
|
||||
def endpoint_delete_responses(cls: Type[OpenApi]) -> Dict[str, Any]:
|
||||
return {}
|
||||
|
||||
@classmethod
|
||||
def endpoint_delete_summary(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def endpoint_delete_tags(cls: Type[OpenApi]) -> List[str]:
|
||||
return []
|
||||
|
||||
@classmethod
|
||||
def endpoint_delete_spec(cls: Type[OpenApi]) -> Dict[str, Any]:
|
||||
description = cls.endpoint_delete_description()
|
||||
if description is None:
|
||||
return {}
|
||||
return {
|
||||
'description': description,
|
||||
'parameters': cls.endpoint_delete_parameters(),
|
||||
'responses': cls.endpoint_with_default_responses(cls.endpoint_delete_responses()),
|
||||
'summary': cls.endpoint_delete_summary(),
|
||||
'tags': cls.endpoint_delete_tags()
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def endpoint_get_description(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return None
|
||||
@ -61,8 +90,8 @@ class OpenApi(Serializable):
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_request_body(cls: Type[OpenApi], content_type: str) -> str:
|
||||
return ''
|
||||
def endpoint_post_request_body(cls: Type[OpenApi], content_type: str) -> List[str]:
|
||||
return []
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_responses(cls: Type[OpenApi]) -> Dict[str, Any]:
|
||||
@ -87,7 +116,10 @@ class OpenApi(Serializable):
|
||||
'requestBody': {
|
||||
'content': {
|
||||
content_type: {
|
||||
'schema': {'$ref': cls.model_ref(cls.endpoint_post_request_body(content_type))}
|
||||
'schema': {'allOf': [
|
||||
{'$ref': cls.model_ref(ref)}
|
||||
for ref in cls.endpoint_post_request_body(content_type)
|
||||
]}
|
||||
}
|
||||
for content_type in cls.endpoint_post_consumes()
|
||||
}
|
||||
@ -97,6 +129,54 @@ class OpenApi(Serializable):
|
||||
'tags': cls.endpoint_post_tags()
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_consumes(cls: Type[OpenApi]) -> List[str]:
|
||||
return ['application/json']
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_description(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_request_body(cls: Type[OpenApi], content_type: str) -> List[str]:
|
||||
return []
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_responses(cls: Type[OpenApi]) -> Dict[str, Any]:
|
||||
return {}
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_summary(cls: Type[OpenApi]) -> Optional[str]:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_tags(cls: Type[OpenApi]) -> List[str]:
|
||||
return []
|
||||
|
||||
@classmethod
|
||||
def endpoint_put_spec(cls: Type[OpenApi]) -> Dict[str, Any]:
|
||||
description = cls.endpoint_put_description()
|
||||
if description is None:
|
||||
return {}
|
||||
return {
|
||||
'consumes': cls.endpoint_put_consumes(),
|
||||
'description': description,
|
||||
'requestBody': {
|
||||
'content': {
|
||||
content_type: {
|
||||
'schema': {'allOf': [
|
||||
{'$ref': cls.model_ref(ref)}
|
||||
for ref in cls.endpoint_put_request_body(content_type)
|
||||
]}
|
||||
}
|
||||
for content_type in cls.endpoint_put_consumes()
|
||||
}
|
||||
},
|
||||
'responses': cls.endpoint_with_default_responses(cls.endpoint_put_responses()),
|
||||
'summary': cls.endpoint_put_summary(),
|
||||
'tags': cls.endpoint_put_tags()
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def endpoint_spec(cls: Type[OpenApi], operations: List[str]) -> Dict[str, Any]:
|
||||
return {
|
||||
|
@ -54,8 +54,8 @@ class PlayerView(PlayerBaseView, OpenApi):
|
||||
return 'Create new party player or remove existing'
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_request_body(cls: Type[OpenApi], content_type: str) -> str:
|
||||
return 'PlayerEdit'
|
||||
def endpoint_post_request_body(cls: Type[OpenApi], content_type: str) -> List[str]:
|
||||
return ['PlayerEdit']
|
||||
|
||||
@classmethod
|
||||
def endpoint_post_responses(cls: Type[OpenApi]) -> Dict[str, Any]:
|
||||
|
@ -10,6 +10,7 @@ from aiohttp.web import View
|
||||
from typing import List, Optional
|
||||
|
||||
from service.core.ariyala_parser import AriyalaParser
|
||||
from service.models.bis import BiS
|
||||
from service.models.piece import Piece
|
||||
from service.models.player import PlayerId
|
||||
|
||||
@ -35,13 +36,13 @@ class BiSBaseView(View):
|
||||
return await self.bis_remove(player_id, piece)
|
||||
return None
|
||||
|
||||
async def bis_put(self, player_id: PlayerId, link: str) -> str:
|
||||
async def bis_put(self, player_id: PlayerId, link: str) -> BiS:
|
||||
parser = AriyalaParser(self.request.app['config'])
|
||||
items = parser.get(link, player_id.job.name)
|
||||
for piece in items:
|
||||
await self.request.app['party'].set_item_bis(player_id, piece)
|
||||
await self.request.app['party'].set_bis_link(player_id, link)
|
||||
return link
|
||||
return self.request.app['party'].players[player_id].bis
|
||||
|
||||
async def bis_remove(self, player_id: PlayerId, piece: Piece) -> Piece:
|
||||
await self.request.app['party'].remove_item_bis(player_id, piece)
|
||||
|
@ -11,11 +11,42 @@ import itertools
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Dict, List, Optional, Type, Union
|
||||
|
||||
from .job import Job
|
||||
from .piece import Piece
|
||||
from .serializable import Serializable
|
||||
from .upgrade import Upgrade
|
||||
|
||||
|
||||
@dataclass
|
||||
class BiSLink(Serializable):
|
||||
nick: str
|
||||
job: Job
|
||||
link: str
|
||||
|
||||
@classmethod
|
||||
def model_properties(cls: Type[Serializable]) -> Dict[str, Any]:
|
||||
return {
|
||||
'job': {
|
||||
'description': 'player job name',
|
||||
'$ref': cls.model_ref('Job')
|
||||
},
|
||||
'link': {
|
||||
'description': 'link to BiS set',
|
||||
'example': 'https://ffxiv.ariyala.com/19V5R',
|
||||
'type': 'string'
|
||||
},
|
||||
'nick': {
|
||||
'description': 'player nick name',
|
||||
'example': 'Siuan Sanche',
|
||||
'type': 'string'
|
||||
}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def model_required(cls: Type[Serializable]) -> List[str]:
|
||||
return ['job', 'link', 'nick']
|
||||
|
||||
|
||||
@dataclass
|
||||
class BiS(Serializable):
|
||||
weapon: Optional[Piece] = None
|
||||
|
@ -7,13 +7,31 @@
|
||||
# License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
|
||||
#
|
||||
from dataclasses import dataclass
|
||||
from typing import Union
|
||||
from typing import Any, Dict, List, Type, Union
|
||||
|
||||
from .piece import Piece
|
||||
from .serializable import Serializable
|
||||
from .upgrade import Upgrade
|
||||
|
||||
|
||||
@dataclass
|
||||
class Loot:
|
||||
class Loot(Serializable):
|
||||
player_id: int
|
||||
piece: Union[Piece, Upgrade]
|
||||
piece: Union[Piece, Upgrade]
|
||||
|
||||
@classmethod
|
||||
def model_properties(cls: Type[Serializable]) -> Dict[str, Any]:
|
||||
return {
|
||||
'piece': {
|
||||
'description': 'player piece',
|
||||
'$ref': cls.model_ref('Piece')
|
||||
},
|
||||
'player_id': {
|
||||
'description': 'player identifier',
|
||||
'$ref': cls.model_ref('PlayerId')
|
||||
}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def model_required(cls: Type[Serializable]) -> List[str]:
|
||||
return ['piece', 'player_id']
|
@ -86,7 +86,6 @@ class Piece(Serializable):
|
||||
},
|
||||
'name': {
|
||||
'description': 'piece name',
|
||||
'required': True,
|
||||
'type': 'string'
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +66,48 @@ class PlayerIdWithCounters(PlayerId):
|
||||
loot_count_total: int
|
||||
bis_count_total: int
|
||||
|
||||
@classmethod
|
||||
def model_properties(cls: Type[Serializable]) -> Dict[str, Any]:
|
||||
return {
|
||||
'bis_count_total': {
|
||||
'description': 'total savage pieces in BiS',
|
||||
'type': 'integer'
|
||||
},
|
||||
'is_required': {
|
||||
'description': 'is item required by BiS or not',
|
||||
'type': 'boolean'
|
||||
},
|
||||
'job': {
|
||||
'description': 'player job name',
|
||||
'$ref': cls.model_ref('Job')
|
||||
},
|
||||
'loot_count': {
|
||||
'description': 'count of this item which was already looted',
|
||||
'type': 'integer'
|
||||
},
|
||||
'loot_count_bis': {
|
||||
'description': 'count of BiS items which were already looted',
|
||||
'type': 'integer'
|
||||
},
|
||||
'loot_count_total': {
|
||||
'description': 'total count of items which were looted',
|
||||
'type': 'integer'
|
||||
},
|
||||
'nick': {
|
||||
'description': 'player nick name',
|
||||
'type': 'string'
|
||||
},
|
||||
'priority': {
|
||||
'description': 'player loot priority',
|
||||
'type': 'integer'
|
||||
}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def model_required(cls: Type[Serializable]) -> List[str]:
|
||||
return ['bis_count_total', 'is_required', 'job', 'loot_count',
|
||||
'loot_count_bis', 'loot_count_total', 'nick', 'priority']
|
||||
|
||||
|
||||
@dataclass
|
||||
class Player(Serializable):
|
||||
|
@ -7,10 +7,36 @@
|
||||
# License: 3-clause BSD, see https://opensource.org/licenses/BSD-3-Clause
|
||||
#
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Dict, List, Type
|
||||
|
||||
from .serializable import Serializable
|
||||
|
||||
|
||||
@dataclass
|
||||
class User:
|
||||
class User(Serializable):
|
||||
username: str
|
||||
password: str
|
||||
permission: str
|
||||
permission: str
|
||||
|
||||
@classmethod
|
||||
def model_properties(cls: Type[Serializable]) -> Dict[str, Any]:
|
||||
return {
|
||||
'password': {
|
||||
'description': 'user password',
|
||||
'type': 'string'
|
||||
},
|
||||
'permission': {
|
||||
'default': 'get',
|
||||
'description': 'user action permissions',
|
||||
'type': 'string',
|
||||
'enum': ['admin', 'get', 'post']
|
||||
},
|
||||
'username': {
|
||||
'description': 'user name',
|
||||
'type': 'string'
|
||||
}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def model_required(cls: Type[Serializable]) -> List[str]:
|
||||
return ['password', 'username']
|
Loading…
Reference in New Issue
Block a user