Add animesoul client & rpc server
This commit is contained in:
commit
792edb4c88
6 changed files with 163 additions and 0 deletions
33
README.md
Normal file
33
README.md
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# jaken
|
||||||
|
|
||||||
|
Python component of Kirara, responds to RPC
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
```sh
|
||||||
|
python3 -m venv env
|
||||||
|
./env/bin/pip install -r requirements.txt
|
||||||
|
|
||||||
|
# running the server
|
||||||
|
./env/bin/python -m jaken
|
||||||
|
```
|
||||||
|
|
||||||
|
## RPC directory
|
||||||
|
|
||||||
|
### `soul`
|
||||||
|
|
||||||
|
Searching for cards:
|
||||||
|
```js
|
||||||
|
rpc.remote.soul.search_cards("blake").then((cards) => {
|
||||||
|
// `cards` is an array of cards
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Fetching a specific card by ID:
|
||||||
|
```js
|
||||||
|
rpc.remote.soul.get_card("5f2b3701a5a84e32a258df1b", /* with_users: */ true)
|
||||||
|
.then((data) => {
|
||||||
|
// `data.card` is a Card
|
||||||
|
// if with_users is true, `data.users` is an array of users
|
||||||
|
});
|
||||||
|
```
|
22
jaken/__init__.py
Normal file
22
jaken/__init__.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
from jaken.rpc import SoulServer
|
||||||
|
|
||||||
|
import aiomas
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
soul_service = SoulServer()
|
||||||
|
await soul_service.connect()
|
||||||
|
|
||||||
|
root_service = aiomas.rpc.ServiceDict({
|
||||||
|
"soul": soul_service,
|
||||||
|
})
|
||||||
|
|
||||||
|
rpc_server = await aiomas.rpc.start_server(('localhost', 5444), root_service)
|
||||||
|
|
||||||
|
try:
|
||||||
|
await soul_service.soul_client.run()
|
||||||
|
finally:
|
||||||
|
rpc_server.close()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
5
jaken/__main__.py
Normal file
5
jaken/__main__.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
from jaken import main
|
||||||
|
|
||||||
|
asyncio.run(main())
|
30
jaken/rpc.py
Normal file
30
jaken/rpc.py
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import aiomas
|
||||||
|
|
||||||
|
from jaken.soul import SoulClient, Card
|
||||||
|
|
||||||
|
class SoulServer:
|
||||||
|
router = aiomas.rpc.Service()
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.soul_client = SoulClient()
|
||||||
|
|
||||||
|
async def connect(self):
|
||||||
|
await self.soul_client.connect()
|
||||||
|
|
||||||
|
@router.expose
|
||||||
|
async def search_cards(self, search_term):
|
||||||
|
r = await self.soul_client.call("cardindex", {"search": search_term})
|
||||||
|
cards = [Card(doc).to_dict() for doc in r['data']['docs']]
|
||||||
|
|
||||||
|
return cards
|
||||||
|
|
||||||
|
@router.expose
|
||||||
|
async def get_card(self, card_id, with_users=False):
|
||||||
|
r = await self.soul_client.call("cardview", {"cardid": card_id})
|
||||||
|
card = Card(r['card']).to_dict()
|
||||||
|
users = r['users']
|
||||||
|
|
||||||
|
if with_users:
|
||||||
|
return dict(card=card, users=users)
|
||||||
|
else:
|
||||||
|
return dict(card=card)
|
71
jaken/soul.py
Normal file
71
jaken/soul.py
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
import asyncio
|
||||||
|
import socketio
|
||||||
|
|
||||||
|
class PatchedAsyncClient(socketio.AsyncClient):
|
||||||
|
async def _handle_event(self, namespace, id, data):
|
||||||
|
namespace = namespace or '/'
|
||||||
|
await super()._handle_event(namespace, id, data)
|
||||||
|
await self._trigger_event('message', namespace, *data[1:])
|
||||||
|
|
||||||
|
class SoulClient:
|
||||||
|
def __init__(self):
|
||||||
|
self.sio = PatchedAsyncClient(logger=True)
|
||||||
|
self.sio.on('connect', self._on_connect)
|
||||||
|
self.sio.on('message', self._on_message)
|
||||||
|
|
||||||
|
self.call_lock = asyncio.Lock()
|
||||||
|
self.callback = None
|
||||||
|
|
||||||
|
async def _on_connect(self, namespace=None):
|
||||||
|
await self.call('init')
|
||||||
|
|
||||||
|
async def _on_message(self, msg):
|
||||||
|
if self.call_lock.locked():
|
||||||
|
self.call_lock.release()
|
||||||
|
if self.callback:
|
||||||
|
self.callback.set_result(msg)
|
||||||
|
|
||||||
|
async def connect(self):
|
||||||
|
await self.sio.connect("wss://animesoul.com/socket.io/", transports=['websocket'])
|
||||||
|
|
||||||
|
async def run(self):
|
||||||
|
await self.sio.wait()
|
||||||
|
|
||||||
|
async def cast(self, event_name, data=None):
|
||||||
|
await self.sio.emit(event_name, data)
|
||||||
|
|
||||||
|
async def call(self, event_name, data=None):
|
||||||
|
await self.call_lock.acquire()
|
||||||
|
await self.sio.emit(event_name, data)
|
||||||
|
|
||||||
|
self.callback = asyncio.get_event_loop().create_future()
|
||||||
|
return await self.callback
|
||||||
|
|
||||||
|
class Card:
|
||||||
|
IMAGE_CDN = "https://cdn.animesoul.com/images/cards"
|
||||||
|
|
||||||
|
def __init__(self, kwargs):
|
||||||
|
self.pk = kwargs.get("_id")
|
||||||
|
self.name = kwargs.get("name")
|
||||||
|
self.slug = kwargs.get("slug")
|
||||||
|
self.tier = kwargs.get("tier")
|
||||||
|
self.claim_count = kwargs.get("claim_count")
|
||||||
|
|
||||||
|
extra = kwargs.get("category")
|
||||||
|
try:
|
||||||
|
self.anime = extra[0]
|
||||||
|
except IndexError:
|
||||||
|
self.anime = None
|
||||||
|
|
||||||
|
self.filename = kwargs.get("file")
|
||||||
|
self.url = f"{self.IMAGE_CDN}/{self.tier}/{self.filename}"
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return {
|
||||||
|
"id": self.pk,
|
||||||
|
"name": self.name,
|
||||||
|
"tier": self.tier,
|
||||||
|
"anime": self.anime,
|
||||||
|
"link": self.url,
|
||||||
|
"claim_count": self.claim_count,
|
||||||
|
}
|
2
requirements.txt
Normal file
2
requirements.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
python-socketio[asyncio_client]==4.6.0
|
||||||
|
aiomas==2.0.1
|
Loading…
Reference in a new issue