Skip to content

Commit

Permalink
Merge pull request #154 from LazoCoder/mac-ss-fix
Browse files Browse the repository at this point in the history
Fix macOS slideshow
  • Loading branch information
sylveon authored Aug 12, 2018
2 parents 72cff03 + 271b12c commit 09d3429
Show file tree
Hide file tree
Showing 11 changed files with 66 additions and 53 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ Alternatively, you can delete images from this folder and it will not break the
$ sudo apt-get update
$ sudo apt install terminology
```
* If you get the error `39:46: syntax error: Expected end of line but found identifier. (-2741)`: Locate the file `ITerm.py` in `pokemonterminal/terminal/adapters` and on line 9, change `iTerm` to `iTerm2`. If you still experience the error, try changing it to `iTerm 2`.

## Saving

Expand Down
2 changes: 1 addition & 1 deletion pokemonterminal/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
"""


__version__ = "1.1.0"
__version__ = "1.2.0"
__author__ = "LazoCoder"
12 changes: 8 additions & 4 deletions pokemonterminal/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ def main(argv=None):
return

if is_slideshow and options.id <= 0 and size > 1:
if options.slideshow <= 0:
print("Time has to be greater than 0. You can use decimal values.")
return
if event_exists:
print("One or more slideshows is already running.\n")
while True:
Expand All @@ -97,11 +100,12 @@ def main(argv=None):
return
else:
print("Not a valid option!\n")
if options.slideshow <= 0:
print("Time has to be greater then 0. You can use decimal values.")
return
target_func = scripter.change_wallpaper if options.wallpaper else scripter.change_terminal
slideshow.start(Filter.filtered_list, options.slideshow, target_func, event_name)
print(f"Starting slideshow with {len(Filter.filtered_list)} Pokemons and a delay of {options.slideshow} minutes.")
pid = slideshow.start(Filter.filtered_list, options.slideshow, target_func, event_name)
print(f"Forked process to background with PID {pid}.")
print("You can stop it with 'pokemon {}'.".format('-c -w' if options.wallpaper else '-c'))
return

if options.wallpaper:
scripter.change_wallpaper(target.get_path())
Expand Down
49 changes: 36 additions & 13 deletions pokemonterminal/platform/named_event/posix.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,58 @@
import errno
import os
import psutil
import stat
import sys
import time

from . import NamedEvent
from unittest.mock import patch
from pathlib import PosixPath

def _isfifo_strict(path):
# https://github.com/giampaolo/psutil/blob/release-5.4.6/psutil/_common.py#L362
try:
st = os.stat(path)
except OSError as err:
if err.errno in (errno.EPERM, errno.EACCES):
raise
return False
else:
return stat.S_ISFIFO(st.st_mode)

class PosixNamedEvent(NamedEvent):
"""
A wrapper for named events using a FIFO (named pipe)
"""

__self_references = ['self', str(os.getpid()), 'thread-self']

@staticmethod
def __build_fifo_path(name: str) -> PosixPath:
return PosixPath('/') / 'run' / 'user' / str(os.getuid()) / 'pokemon-terminal' / name
return PosixPath(f'/tmp/{name}/{os.getuid()}')

@staticmethod
def __generate_handle_list() -> [PosixPath]:
for p in PosixPath('/proc').glob('*/fd/*'):
if not any(p.parts[2] == s for s in PosixNamedEvent.__self_references):
yield p.resolve()
def __has_open_file_handles_real(path: PosixPath) -> bool:
for proc in psutil.process_iter():
try:
if proc.pid != os.getpid():
for file in proc.open_files():
if PosixPath(file.path).samefile(path):
return True
except psutil.Error:
continue
return False

@staticmethod
def __has_open_file_handles(path: PosixPath) -> bool:
if sys.platform != 'darwin':
realpath = path.resolve()
return any(realpath == p for p in PosixNamedEvent.__generate_handle_list())
else:
# TODO
raise NotImplementedError("macOS doesn't have /proc")
# HACK psutil explicitely filters out FIFOs from open_files()
# HACK patch the function responsible of it so it does the reverse instead
# HACK (only enumerate FIFOs in open_files)
try:
with patch("psutil._psplatform.isfile_strict", _isfifo_strict):
return PosixNamedEvent.__has_open_file_handles_real(path)
except:
# Something happened(tm), or the platform doesn't uses isfile_strict (ex: BSD).
# Do a best effort.
return PosixNamedEvent.__has_open_file_handles_real(path)

def exists(name: str) -> bool:
p = PosixNamedEvent.__build_fifo_path(name)
Expand Down
4 changes: 2 additions & 2 deletions pokemonterminal/scripter.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def __init_terminal_provider():
if len(providers) > 1:
# All this if is really not supposed to happen at all whatsoever
# really what kind of person has 2 simultaneous T.E???
print("Multiple providers found select the appropriate one:")
print("Multiple providers found, please select the appropriate one.")
for i, x in enumerate(providers):
print(f'{i}. {x.__str__()}')
print("If some of these make no sense or are irrelevant please file " +
Expand Down Expand Up @@ -46,7 +46,7 @@ def __init_wallpaper_provider():
if len(providers) > 1:
# All this if is really not supposed to happen at all whatsoever
# really what kind of person has 2 simultaneous D.E???
print("Multiple providers found select the appropriate one:")
print("Multiple providers found, please select the appropriate one.")
for i, x in enumerate(providers):
print(f'{i}. {x.__str__()}')
print("If some of these make no sense or are irrelevant please file " +
Expand Down
8 changes: 1 addition & 7 deletions pokemonterminal/slideshow.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@
from .platform import PlatformNamedEvent
from threading import Thread

def __print_fork(pid, length, delay):
print(f"Starting slideshow with {length} Pokemons and a delay of {delay} minutes.")
print(f"Forked process to background with PID {pid}.")
print("You can stop it with 'pokemon -c'. (add '-w' if this is a wallpaper slideshow)")

def __event_listener(event):
event.wait()

Expand All @@ -36,10 +31,9 @@ def __slideshow_worker(filtered, delay, changer_func, event_name):
def start(filtered, delay, changer_func, event_name):
p = multiprocessing.Process(target=__slideshow_worker, args=(filtered, delay, changer_func, event_name, ), daemon=True)
p.start()
__print_fork(p.pid, len(filtered), delay)
# HACK remove multiprocessing's exit handler to prevent it killing our child.
atexit.unregister(multiprocessing.util._exit_function)
sys.exit(0)
return p.pid

def stop(event_name):
with PlatformNamedEvent(event_name) as e:
Expand Down
18 changes: 7 additions & 11 deletions pokemonterminal/terminal/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import importlib
import inspect
import pathlib

from .adapters import TerminalProvider


Expand All @@ -16,17 +17,12 @@ def _get_adapter_classes() -> [TerminalProvider]:
all the implementing wallpaper adapter classes
thanks for/adapted from https://github.com/cclauss/adapter_pattern/
"""
dirname = os.path.join(os.path.dirname(
os.path.abspath(__file__)), 'adapters')
adapter_classes = []
for file_name in sorted(os.listdir(dirname)):
root, ext = os.path.splitext(file_name)
if ext.lower() == '.py' and not root.startswith('__'):
module = importlib.import_module(
'.' + root, 'pokemonterminal.terminal.adapters')
adapter_dir = pathlib.Path(__file__).resolve().parent / 'adapters'
for file in adapter_dir.iterdir():
if file.suffix.lower() == '.py' and not file.name.startswith('__'):
module = importlib.import_module('.' + file.name.split('.')[0], 'pokemonterminal.terminal.adapters')
for _, c in inspect.getmembers(module, _is_adapter):
adapter_classes.append(c)
return adapter_classes
yield c


def get_current_terminal_adapters() -> [TerminalProvider]:
Expand Down
18 changes: 7 additions & 11 deletions pokemonterminal/wallpaper/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import importlib
import inspect
import pathlib

from .adapters import WallpaperProvider


Expand All @@ -16,17 +17,12 @@ def _get_adapter_classes() -> [WallpaperProvider]:
all the implementing wallpaper adapter classes
thanks for/adapted from https://github.com/cclauss/adapter_pattern/
"""
dirname = os.path.join(os.path.dirname(
os.path.abspath(__file__)), 'adapters')
adapter_classes = []
for file_name in sorted(os.listdir(dirname)):
root, ext = os.path.splitext(file_name)
if ext.lower() == '.py' and not root.startswith('__'):
module = importlib.import_module(
'.' + root, 'pokemonterminal.wallpaper.adapters')
adapter_dir = pathlib.Path(__file__).resolve().parent / 'adapters'
for file in adapter_dir.iterdir():
if file.suffix.lower() == '.py' and not file.name.startswith('__'):
module = importlib.import_module('.' + file.name.split('.')[0], 'pokemonterminal.wallpaper.adapters')
for _, c in inspect.getmembers(module, _is_adapter):
adapter_classes.append(c)
return adapter_classes
yield c


def get_current_wallpaper_adapters() -> [WallpaperProvider]:
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,6 @@ def package_data(relpath, folders):
"Programming Language :: Python :: 3.6"
],

python_requires=">=3.6"
python_requires=">=3.6",
install_requires=(["psutil"] if sys.platform != "win32" else None)
)
2 changes: 1 addition & 1 deletion tests/test_terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@


def test_terminal_adapter_classes():
all_adapter = _get_adapter_classes()
all_adapter = list(_get_adapter_classes())
files = {__inspct.getfile(x) for x in all_adapter}
print('all adapter classes:\n', files)
assert len(all_adapter) >= len(files), \
Expand Down
2 changes: 1 addition & 1 deletion tests/test_wallpaper.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@


def test_wallpaper_adapter_classes():
all_adapter = _get_adapter_classes()
all_adapter = list(_get_adapter_classes())
files = {__inspct.getfile(x) for x in all_adapter}
print('all adapter classes:\n', files)
assert len(all_adapter) >= len(files), \
Expand Down

0 comments on commit 09d3429

Please sign in to comment.