added dependency checking
- Dependency install states will be checked and will be automatically installed if it isn't.
This commit is contained in:
parent
87bd857bfb
commit
32c837bfb2
116
dance.py
116
dance.py
|
@ -1,3 +1,36 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
def check_dependencies():
|
||||||
|
def check_dependency_aiohttp():
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
import aiohttp
|
||||||
|
except:
|
||||||
|
os.system('pip3 install aiohttp==3.7.4')
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
def check_dependency_hidapi():
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
import hid
|
||||||
|
except:
|
||||||
|
os.system('pip3 install hidapi'); os.system('pip3 install hid')
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
def check_dependency_websockets():
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
import websockets
|
||||||
|
except:
|
||||||
|
os.system('pip3 install websockets')
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
check_dependency_aiohttp(); check_dependency_hidapi(); check_dependency_websockets()
|
||||||
|
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
@ -13,33 +46,33 @@ import hid
|
||||||
from aiohttp import WSMsgType, web
|
from aiohttp import WSMsgType, web
|
||||||
|
|
||||||
from joydance import JoyDance, PairingState
|
from joydance import JoyDance, PairingState
|
||||||
from joydance.constants import (DEFAULT_CONFIG, JOYDANCE_VERSION,
|
from joydance.constants import (DEFAULT_CONFIG, JOYDANCE_VERSION, WsSubprotocolVersion)
|
||||||
WsSubprotocolVersion)
|
|
||||||
from pycon import ButtonEventJoyCon, JoyCon
|
from pycon import ButtonEventJoyCon, JoyCon
|
||||||
from pycon.constants import JOYCON_PRODUCT_IDS, JOYCON_VENDOR_ID
|
from pycon.constants import JOYCON_PRODUCT_IDS, JOYCON_VENDOR_ID
|
||||||
|
|
||||||
logging.getLogger('asyncio').setLevel(logging.WARNING)
|
logging.getLogger('asyncio').setLevel(logging.WARNING)
|
||||||
|
|
||||||
|
def main():
|
||||||
class WsCommand(Enum):
|
try:
|
||||||
|
class WsCommand(Enum):
|
||||||
GET_JOYCON_LIST = 'get_joycon_list'
|
GET_JOYCON_LIST = 'get_joycon_list'
|
||||||
CONNECT_JOYCON = 'connect_joycon'
|
CONNECT_JOYCON = 'connect_joycon'
|
||||||
DISCONNECT_JOYCON = 'disconnect_joycon'
|
DISCONNECT_JOYCON = 'disconnect_joycon'
|
||||||
UPDATE_JOYCON_STATE = 'update_joycon_state'
|
UPDATE_JOYCON_STATE = 'update_joycon_state'
|
||||||
|
|
||||||
|
|
||||||
class PairingMethod(Enum):
|
class PairingMethod(Enum):
|
||||||
DEFAULT = 'default'
|
DEFAULT = 'default'
|
||||||
FAST = 'fast'
|
FAST = 'fast'
|
||||||
STADIA = 'stadia'
|
STADIA = 'stadia'
|
||||||
OLD = 'old'
|
OLD = 'old'
|
||||||
|
|
||||||
|
|
||||||
REGEX_PAIRING_CODE = re.compile(r'^\d{6}$')
|
REGEX_PAIRING_CODE = re.compile(r'^\d{6}$')
|
||||||
REGEX_LOCAL_IP_ADDRESS = re.compile(r'^(192\.168|10.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5]))\.((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.)(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$')
|
REGEX_LOCAL_IP_ADDRESS = re.compile(r'^(192\.168|10.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5]))\.((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.)(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$')
|
||||||
|
|
||||||
|
|
||||||
async def get_device_ids():
|
async def get_device_ids():
|
||||||
devices = hid.enumerate(JOYCON_VENDOR_ID, 0)
|
devices = hid.enumerate(JOYCON_VENDOR_ID, 0)
|
||||||
|
|
||||||
out = []
|
out = []
|
||||||
|
@ -65,7 +98,7 @@ async def get_device_ids():
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
async def get_joycon_list(app):
|
async def get_joycon_list(app):
|
||||||
joycons = []
|
joycons = []
|
||||||
devices = await get_device_ids()
|
devices = await get_device_ids()
|
||||||
|
|
||||||
|
@ -106,7 +139,7 @@ async def get_joycon_list(app):
|
||||||
return sorted(joycons, key=lambda x: (x['name'], x['color'], x['serial']))
|
return sorted(joycons, key=lambda x: (x['name'], x['color'], x['serial']))
|
||||||
|
|
||||||
|
|
||||||
async def connect_joycon(app, ws, data):
|
async def connect_joycon(app, ws, data):
|
||||||
async def on_joydance_state_changed(serial, state):
|
async def on_joydance_state_changed(serial, state):
|
||||||
print(serial, state)
|
print(serial, state)
|
||||||
app['joycons_info'][serial]['state'] = state.value
|
app['joycons_info'][serial]['state'] = state.value
|
||||||
|
@ -171,7 +204,7 @@ async def connect_joycon(app, ws, data):
|
||||||
asyncio.create_task(joydance.pair())
|
asyncio.create_task(joydance.pair())
|
||||||
|
|
||||||
|
|
||||||
async def disconnect_joycon(app, ws, data):
|
async def disconnect_joycon(app, ws, data):
|
||||||
print(data)
|
print(data)
|
||||||
serial = data['joycon_serial']
|
serial = data['joycon_serial']
|
||||||
joydance = app['joydance_connections'][serial]
|
joydance = app['joydance_connections'][serial]
|
||||||
|
@ -187,7 +220,7 @@ async def disconnect_joycon(app, ws, data):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def parse_config():
|
def parse_config():
|
||||||
parser = ConfigParser()
|
parser = ConfigParser()
|
||||||
parser.read('config.cfg')
|
parser.read('config.cfg')
|
||||||
|
|
||||||
|
@ -226,15 +259,15 @@ def parse_config():
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
def is_valid_pairing_code(val):
|
def is_valid_pairing_code(val):
|
||||||
return re.match(REGEX_PAIRING_CODE, val) is not None
|
return re.match(REGEX_PAIRING_CODE, val) is not None
|
||||||
|
|
||||||
|
|
||||||
def is_valid_ip_address(val):
|
def is_valid_ip_address(val):
|
||||||
return re.match(REGEX_LOCAL_IP_ADDRESS, val) is not None
|
return re.match(REGEX_LOCAL_IP_ADDRESS, val) is not None
|
||||||
|
|
||||||
|
|
||||||
def is_valid_pairing_method(val):
|
def is_valid_pairing_method(val):
|
||||||
return val in [
|
return val in [
|
||||||
PairingMethod.DEFAULT.value,
|
PairingMethod.DEFAULT.value,
|
||||||
PairingMethod.FAST.value,
|
PairingMethod.FAST.value,
|
||||||
|
@ -243,7 +276,7 @@ def is_valid_pairing_method(val):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def get_host_ip():
|
def get_host_ip():
|
||||||
try:
|
try:
|
||||||
for ip in socket.gethostbyname_ex(socket.gethostname())[2]:
|
for ip in socket.gethostbyname_ex(socket.gethostname())[2]:
|
||||||
if ip.startswith('192.168') or ip.startswith('10.'):
|
if ip.startswith('192.168') or ip.startswith('10.'):
|
||||||
|
@ -254,32 +287,28 @@ def get_host_ip():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def save_config(parser):
|
def save_config(parser):
|
||||||
with open('config.cfg', 'w') as fp:
|
with open('config.cfg', 'w') as fp:
|
||||||
parser.write(fp)
|
parser.write(fp)
|
||||||
|
|
||||||
|
|
||||||
async def on_startup(app):
|
async def on_startup(app):
|
||||||
print('''
|
os.system('clear')
|
||||||
░░ ░░░░░░ ░░ ░░ ░░░░░░ ░░░░░ ░░░ ░░ ░░░░░░ ░░░░░░░
|
|
||||||
▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒▒▒ ▒▒ ▒▒ ▒▒
|
|
||||||
▒▒ ▒▒ ▒▒ ▒▒▒▒ ▒▒ ▒▒ ▒▒▒▒▒▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒▒▒▒
|
|
||||||
▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓
|
|
||||||
█████ ██████ ██ ██████ ██ ██ ██ ████ ██████ ███████
|
|
||||||
|
|
||||||
Open http://localhost:32623 in your browser.''')
|
|
||||||
|
|
||||||
# Check for update
|
# Check for update
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.get('https://api.github.com/repos/redphx/joydance/releases/latest', ssl=False) as resp:
|
async with session.get('https://api.github.com/repos/redphx/joydance/releases/latest', ssl=False) as resp:
|
||||||
json_body = await resp.json()
|
json_body = await resp.json()
|
||||||
latest_version = json_body['tag_name'][1:]
|
latest_version = json_body['tag_name'][1:]
|
||||||
print('Running version {}.'.format(JOYDANCE_VERSION))
|
print('JoyDance V{}.'.format(JOYDANCE_VERSION))
|
||||||
if JOYDANCE_VERSION != latest_version:
|
if JOYDANCE_VERSION != latest_version:
|
||||||
print('\033[93m{}\033[00m'.format('Version {} is available: https://github.com/redphx/joydance'.format(latest_version)))
|
print('\033[93m{}\033[00m'.format('Version {} is available: https://github.com/redphx/joydance'.format(latest_version)))
|
||||||
|
|
||||||
|
time.sleep(2)
|
||||||
|
os.system('open "http://localhost:32623"')
|
||||||
|
|
||||||
async def html_handler(request):
|
|
||||||
|
async def html_handler(request):
|
||||||
config = dict((parse_config()).items('joydance'))
|
config = dict((parse_config()).items('joydance'))
|
||||||
with open('static/index.html', 'r') as f:
|
with open('static/index.html', 'r') as f:
|
||||||
html = f.read()
|
html = f.read()
|
||||||
|
@ -288,7 +317,7 @@ async def html_handler(request):
|
||||||
return web.Response(text=html, content_type='text/html')
|
return web.Response(text=html, content_type='text/html')
|
||||||
|
|
||||||
|
|
||||||
async def ws_send_response(ws, cmd, data):
|
async def ws_send_response(ws, cmd, data):
|
||||||
resp = {
|
resp = {
|
||||||
'cmd': 'resp_' + cmd.value,
|
'cmd': 'resp_' + cmd.value,
|
||||||
'data': data,
|
'data': data,
|
||||||
|
@ -296,7 +325,7 @@ async def ws_send_response(ws, cmd, data):
|
||||||
await ws.send_json(resp)
|
await ws.send_json(resp)
|
||||||
|
|
||||||
|
|
||||||
async def websocket_handler(request):
|
async def websocket_handler(request):
|
||||||
ws = web.WebSocketResponse()
|
ws = web.WebSocketResponse()
|
||||||
await ws.prepare(request)
|
await ws.prepare(request)
|
||||||
|
|
||||||
|
@ -325,21 +354,32 @@ async def websocket_handler(request):
|
||||||
return ws
|
return ws
|
||||||
|
|
||||||
|
|
||||||
def favicon_handler(request):
|
def favicon_handler(request):
|
||||||
return web.FileResponse('static/favicon.png')
|
return web.FileResponse('static/favicon.png')
|
||||||
|
|
||||||
|
|
||||||
app = web.Application()
|
app = web.Application()
|
||||||
app['joydance_connections'] = {}
|
app['joydance_connections'] = {}
|
||||||
app['joycons_info'] = {}
|
app['joycons_info'] = {}
|
||||||
|
|
||||||
app.on_startup.append(on_startup)
|
app.on_startup.append(on_startup)
|
||||||
app.add_routes([
|
app.add_routes([
|
||||||
web.get('/', html_handler),
|
web.get('/', html_handler),
|
||||||
web.get('/favicon.png', favicon_handler),
|
web.get('/favicon.png', favicon_handler),
|
||||||
web.get('/ws', websocket_handler),
|
web.get('/ws', websocket_handler),
|
||||||
web.static('/css', 'static/css'),
|
web.static('/css', 'static/css'),
|
||||||
web.static('/js', 'static/js'),
|
web.static('/js', 'static/js'),
|
||||||
])
|
])
|
||||||
|
|
||||||
web.run_app(app, port=32623)
|
web.run_app(app, port=32623)
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
os.system('clear')
|
||||||
|
return(0)
|
||||||
|
|
||||||
|
except TypeError:
|
||||||
|
os.system('clear')
|
||||||
|
return(0)
|
||||||
|
|
||||||
|
check_dependencies()
|
||||||
|
main()
|
||||||
|
|
Loading…
Reference in New Issue