...
 
Commits (4)
......@@ -63,7 +63,7 @@ Installation
Let NPM handle the installation::
$ cd config-generator
$ npm installn
$ npm install
Running Visplay
---------------
......
......@@ -123,7 +123,7 @@ def loadConf(config: int):
async def race_videos(asset, sources):
"""Starts a race between the current video and the configuration watchers.
If the configuration code wins, the function returns true"""
session = aiohttp.ClientSession()
session: aiohttp.ClientSession = aiohttp.ClientSession()
# Sinks accept instructions on what to play and return back the video progress
# Watches for the video to finish
video_watch = asyncio.create_task(run_sinks(session, Config.sinks, asset))
......
......@@ -63,7 +63,7 @@ class Config(metaclass=Singleton):
'cool'
"""
# Default Configuration locations
_config_folder = (environ.get('XDG_CONFIG_HOME') or
_config_folder = (environ.get('XDG_CONFIG_HOME') or environ.get('APPDATA') or
path.join(environ.get('HOME'), '.config'))
_config_folder = path.join(_config_folder, 'visplay')
default_config = path.join(_config_folder, 'config.yaml')
......
from visplay.sources import source_constructors as sc
import uri
from visplay.sources import source_constructors as sc, Source
from uri import URI
from typable import List
import asyncio
from aiohttp import ClientSession
async def run_sinks(session, sinks, asset):
async def run_sinks(session: ClientSession, sinks: List[Source], asset: URI):
tvs = []
for sink in sinks:
path = uri.URI(sink)
path = URI(sink)
tvs.append(sc[str(path.scheme)].play(session, path, asset))
await asyncio.gather(*tvs)
......@@ -42,7 +42,8 @@ def get_sources_list(source_stream):
if 'addTo' in path.query:
playlist_name = path.query['addTo']
playlist = list(filter(lambda a: type(a) == str, new_source.assets))
random.shuffle(playlist)
if 'shuffle' in path.query:
random.shuffle(playlist)
new_source.assets[playlist_name] = playlist
all_sources.append(new_source)
......
......@@ -24,22 +24,22 @@ from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
from visplay.setup_sources import get_sources_list, sources_to_asset
from typing import Dict, List, NewType
from typing import Dict, List, cast
from aiohttp import ClientSession
# Every source needs to say whether the files it gets survive after an error,
# how to get an asset file, and how to get a playlist file.
Assets = NewType('Asset', Dict[str, URI])
def get_local_yaml(yaml_path: str) -> Assets:
def get_local_yaml(yaml_path: Path) -> Dict[str, URI]:
if yaml_path is None:
return
return {}
try:
with open(yaml_path) as yaml_file:
return yaml.load(yaml_file)
except OSError:
return {'error': 'An error parsing the yaml'}
raise Exception(f'{yaml_path} does not exist.')
class Source:
......@@ -47,30 +47,33 @@ class Source:
do the loading of the source.
"""
def __init__(self, name, uri: URI, is_import=False):
def __init__(self, name, uri: URI, is_import: bool = False) -> None:
"""Initialize a source.
Arguments:
"""
self.assets: Assets = {}
self.assets: Dict[str, URI] = {}
self.sources: List[Source] = []
self.layout = None
self.is_import = is_import
def __repr__(self):
def __repr__(self) -> str:
return f'<{type(self).__name__} assets={self.assets} sources={self.sources}>'
async def new_content(self):
async def new_content(self) -> bool:
"""Returns true if the source has changed and false if it hasn't"""
return False
def close(self):
def close(self) -> None:
"""Clean any resources being used"""
pass
async def play(self, session: ClientSession, url: URI, asset: str) -> None:
pass
class HTTPSource(Source):
def __init__(self, name, uri: URI, is_import=False):
def __init__(self, name: str, uri: URI, is_import: bool = False) -> None:
super().__init__(name, uri, is_import=is_import)
self.uri = uri
self.hashUri = (self.uri / self.uri.path.parent / f'{self.uri.path.stem}.meta').uri
......@@ -82,20 +85,20 @@ class HTTPSource(Source):
self.layout = None
else:
with requests.get(uri.base, verify=False) as remote_file:
self.assets = yaml.load(remote_file.content)
self.assets = yaml.load(remote_file.text)
except ConnectionError:
return {'error': 'URL not available'}
pass
self.hash = requests.get(self.hashUri, verify=False).text
async def play(session, url, asset):
async def play(self, session: ClientSession, url: URI, asset: str) -> None:
await session.post(
(url / 'backbuffer/change_layout').uri,
json={'layout': 4, 'header': '', 'path': asset})
await session.post((url / 'swap_buffers').uri)
await session.get((url / '/long_poll_test').uri)
async def new_content(self):
async def new_content(self) -> bool:
session = aiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False))
h = await session.get(self.hashUri)
h = await h.text()
......@@ -105,7 +108,7 @@ class HTTPSource(Source):
return True
return False
def close(self):
def close(self) -> None:
pass
......@@ -115,7 +118,7 @@ class IPFSSource(Source):
If the source
"""
def __init__(self, name, uri: URI, is_import=False):
def __init__(self, name: str, uri: URI, is_import: bool = False) -> None:
super().__init__(name, uri, is_import=is_import)
......@@ -130,9 +133,9 @@ class PathSource(Source):
the name of the asset.
"""
def __init__(self, name, uri: URI, is_import=False):
def __init__(self, name: str, uri: URI, is_import: bool = False) -> None:
super().__init__(name, uri, is_import=is_import)
path = Path(uri.path)
path: Path = Path(uri.path)
self.observer = Observer()
self.updated = False
event_handler = PatternMatchingEventHandler(patterns=[os.fspath(uri.path)])
......@@ -143,7 +146,7 @@ class PathSource(Source):
if not os.path.exists(path):
raise Exception(f'{path} does not exist.')
for file in (os.listdir(path) if os.path.isdir(path) else [path]):
for file in (cast(List[Path], os.listdir(path)) if os.path.isdir(path) else [path]):
file_path = path.joinpath(file)
if file_path.suffix == '.yaml':
......@@ -161,13 +164,13 @@ class PathSource(Source):
else:
self.assets[file_path.name] = str(file_path)
def update_file(self, a):
def update_file(self, _) -> None:
self.updated = True
async def new_content(self):
async def new_content(self) -> bool:
return self.updated
def close(self):
def close(self) -> None:
self.observer.stop()
......