Skip to content

Commit

Permalink
Merge b009dd8 into bed86b5
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMaximum committed Nov 3, 2019
2 parents bed86b5 + b009dd8 commit 9638146
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 4 deletions.
8 changes: 7 additions & 1 deletion pyplanet/apps/contrib/mx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from pyplanet.apps.config import AppConfig
from pyplanet.apps.contrib.mx.api import MXApi
from pyplanet.apps.contrib.mx.exceptions import MXMapNotFound, MXInvalidResponse
from pyplanet.apps.contrib.mx.view import MxSearchListView, MxPacksListView
from pyplanet.apps.contrib.mx.view import MxSearchListView, MxPacksListView, MxStatusListView
from pyplanet.contrib.command import Command
from pyplanet.contrib.setting import Setting
from collections import namedtuple
Expand Down Expand Up @@ -49,6 +49,7 @@ async def on_start(self):
Command(command='search', namespace='mx', target=self.search_mx_map, perms='mx:add_remote', admin=True),
Command(command='add', namespace='mx', target=self.add_mx_map, perms='mx:add_remote', admin=True).add_param(
'maps', nargs='*', type=str, required=True, help='MX ID(s) of maps to add.'),
Command(command='status', namespace='mx', target=self.status_mx_maps, perms='mx:add_remote', admin=True),

# new mxpack namespace
Command(command='search', namespace='mxpack', target=self.search_mx_pack, perms='mx:add_remote',
Expand Down Expand Up @@ -101,6 +102,11 @@ async def search_mx_map(self, player, data, **kwargs):
window = MxSearchListView(self, player, self.api)
await window.display()

async def status_mx_maps(self, player, data, **kwargs):
self.api.key = await self.setting_mx_key.get_value()
window = MxStatusListView(self, self.api)
await window.display(player=player)

async def add_mx_pack(self, player, data, **kwargs):
try:
pack_id = data.pack[0]
Expand Down
17 changes: 16 additions & 1 deletion pyplanet/apps/contrib/mx/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import logging

import aiohttp
import math

from pyplanet import __version__ as pyplanet_version
from pyplanet.apps.contrib.mx.exceptions import MXMapNotFound, MXInvalidResponse
Expand All @@ -18,6 +19,7 @@ def __init__(self, server_login=None):
self.session = None
self.site = None
self.key = None
self.map_info_page_size = 50

async def create_session(self):
self.session = await aiohttp.ClientSession(
Expand Down Expand Up @@ -99,9 +101,22 @@ async def search_pack(self, options, **kwargs):
return maps

async def map_info(self, *ids):
if isinstance(ids[0], str) or isinstance(ids[0], int):
# In case just one value is being passed, put it into an array.
ids = [ids]

# Split the map identifiers into groups, as the ManiaExchange API only accepts a limited amount of maps in one request.
map_ids = ids[0]
split_map_ids = [map_ids[i * self.map_info_page_size:(i + 1) * self.map_info_page_size] for i in range((len(map_ids) + self.map_info_page_size - 1) // self.map_info_page_size)]
split_results = [await self.map_info_page(split_ids) for split_ids in split_map_ids]

# Join the multiple result lists back into one list.
return [map for map_list in split_results for map in map_list]

async def map_info_page(self, *ids):
url = 'https://api.mania-exchange.com/{site}/maps/{ids}'.format(
site=self.site,
ids=','.join(ids)
ids=','.join(str(id) for id in ids[0])
)
params = {'key': self.key} if self.key else {}
response = await self.session.get(url, params=params)
Expand Down
134 changes: 132 additions & 2 deletions pyplanet/apps/contrib/mx/view.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
"""
Mode Settings Views.
MX List Views.
"""
import asyncio
import logging

from pyplanet.views.generics import ManualListView
from pyplanet.views.generics import ManualListView, ask_confirmation
from pyplanet.apps.contrib.mx.exceptions import MXMapNotFound, MXInvalidResponse
from datetime import datetime
from collections import namedtuple

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -362,3 +364,131 @@ async def do_search(self, name=None, username=None, refresh=True, **terms):

if refresh:
await self.refresh(self.player)


class MxStatusListView(ManualListView):

title = 'Server maps status on Mania-Exchange'
icon_style = 'Icons128x128_1'
icon_substyle = 'Browse'

def __init__(self, app, api):
"""
:param app: App config instance.
:param player: Player instance.
:type app: pyplanet.apps.contrib.mx.app.RealMX
"""
super().__init__()
self.manager = app.context.ui
self.app = app
self.api = api

async def get_fields(self):
fields = [
{
'name': 'ID',
'index': 'index',
'sorting': True,
'searching': True,
'width': 15,
'type': 'label'
},
{
'name': 'Map',
'index': 'map_name',
'sorting': True,
'searching': True,
'width': 91.5,
'type': 'label'
},
{
'name': 'On Server',
'index': 'updated_on_server',
'sorting': True,
'searching': False,
'width': 33,
'type': 'label'
},
{
'name': 'MX Version',
'index': 'mx_version',
'sorting': True,
'searching': False,
'width': 33,
'type': 'label'
},
{
'name': 'Status',
'index': 'version_match',
'sorting': True,
'searching': False,
'width': 25,
'type': 'label'
},
]

# Can only update the map via MX if it's possible to remove the current version.
if 'admin' in self.app.instance.apps.apps:
fields.append({
'name': 'Update',
'index': 'action_update_content',
'sorting': False,
'searching': False,
'width': 20,
'type': 'label',
'action': self.action_update_map
})

return fields

async def action_update_map(self, player, values, instance, **kwargs):
# Check if the map could be updated.
if instance['action_update'] is True:
# Ask for confirmation.
cancel = bool(await ask_confirmation(player, 'Are you sure you want to update map \'{}\'$z$s to the version from MX?'.format(
instance['map_name']
), size='sm'))
if cancel is True:
return

# Remove the current version from the server and add the new one from MX.
mock_remove = namedtuple("data", ["nr"])
await self.app.instance.apps.apps['admin'].map.remove_map(player, mock_remove(nr=instance['map_id']))

mock_add = namedtuple("data", ["maps"])
await self.app.add_mx_map(player, mock_add(maps=[instance['index']]))

# Update the current view.
await self.refresh(player=player)

async def get_data(self):
mx_maps_on_server = [map for map in self.app.instance.map_manager.maps if map.mx_id is not None]
mx_maps_info = await self.api.map_info([map.mx_id for map in mx_maps_on_server])

items = []
for item in mx_maps_on_server:
mx_map = next((mx_map_info for mx_map_info in mx_maps_info if mx_map_info[0] == item.mx_id), None)
version_match = ''
version_match_order = 0
mx_version_date = ''
action_update = False

if mx_map is None:
version_match = 'Not on MX'
version_match_order = 1
elif mx_map[1]['TrackUID'] == item.uid:
version_match = '$0a0Up-to-date'
version_match_order = 2
mx_version_date = datetime.strptime(mx_map[1]['UpdatedAt'], '%Y-%m-%dT%H:%M:%S.%f').strftime("%Y-%m-%d %H:%M:%S")
elif mx_map[1]['TrackUID'] is not item.uid:
version_match = '$00fNew version'
version_match_order = 0
mx_version_date = datetime.strptime(mx_map[1]['UpdatedAt'], '%Y-%m-%dT%H:%M:%S.%f').strftime("%Y-%m-%d %H:%M:%S")
action_update = True

action_update_content = '🔁 Update' if action_update else ' -'
items.append({'map_id': item.id, 'index': item.mx_id, 'map_name': item.name, 'version_match': version_match, 'version_match_order': version_match_order,
'updated_on_server': item.updated_at, 'mx_version': mx_version_date, 'action_update': action_update, 'action_update_content': action_update_content})

items.sort(key=lambda x: x['version_match_order'])
return items

0 comments on commit 9638146

Please sign in to comment.