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
					
				
					 1 changed files with 343 additions and 303 deletions
				
			
		
							
								
								
									
										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…
	
	Add table
		Add a link
		
	
		Reference in a new issue