Skip to content

Commit

Permalink
Merge pull request #12 from aaronkollasch/dev
Browse files Browse the repository at this point in the history
Updates for 1.1.1
  • Loading branch information
aaronkollasch authored Nov 24, 2021
2 parents b654abc + 2db605e commit 3e4fc51
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
if: "contains(env.USING_COVERAGE, matrix.python-version)"
- name: "Upload coverage to Codecov"
if: "contains(env.USING_COVERAGE, matrix.python-version)"
uses: "codecov/codecov-action@v1"
uses: "codecov/codecov-action@v2"
with:
fail_ci_if_error: true

Expand Down
9 changes: 9 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
Changelog for Jupyter-O2
========================

1.1.1 - 2021-11-24
------------------

Added
^^^^^
- Fix segmentation fault on ``import Quartz``
- Fix ``try_quit_xquartz()`` in recent versions of macOS (Use the config option ``KEEP_XQUARTZ`` if quitting XQuartz is not desired.)
- Remove check for root prompt at ``login()``

1.1.0 - 2021-10-25
------------------

Expand Down
2 changes: 1 addition & 1 deletion src/jupyter_o2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
)

__author__ = "Aaron Kollasch"
__date__ = "2021-10-25"
__date__ = "2021-11-24"
__copyright__ = "Copyright 2017-2021, Aaron Kollasch"
__email__ = "[email protected]"
__status__ = "Production"
Expand Down
7 changes: 4 additions & 3 deletions src/jupyter_o2/config_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"RUN_JUPYTER_CALL_FORMAT": "jupyter {subcommand} --port={port} --no-browser",
"PORT_RETRIES": 10,
"FORCE_GETPASS": False,
"KEEP_XQUARTZ": False,
"USE_TWO_FACTOR_AUTHENTICATION": False,
"TWO_FACTOR_AUTHENTICATION_CODE": "1",
"USE_INTERNAL_INTERACTIVE_SESSION": True,
Expand Down Expand Up @@ -118,9 +119,9 @@ def get_base_arg_parser():
help="Code(s) to use with 2FA (1 for auto-push)")
parser.add_argument("-k", "--keepalive", default=False, action='store_true',
help="keep interactive session alive after exiting Jupyter")
parser.add_argument("--kq", "--keepxquartz", dest="keepxquartz", default=False,
action='store_true',
help="do not quit XQuartz")
parser.add_argument("--kq", "--keepxquartz", dest="keepxquartz",
default=JO2_DEFAULTS.get("KEEP_XQUARTZ"),
action='store_true', help="do not quit XQuartz")
parser.add_argument("--force-getpass", dest="forcegetpass", action='store_true',
default=JO2_DEFAULTS.get("FORCE_GETPASS"),
help="use getpass instead of pinentry for password entry")
Expand Down
3 changes: 3 additions & 0 deletions src/jupyter_o2/jupyter-o2.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ INIT_JUPYTER_COMMANDS =
;FORCE_GETPASS = False
# Force the use of getpass instead of pinentry if the pinentry is available

;KEEP_XQUARTZ = False
# Do not quit XQuartz after starting Jupyter-O2


[Remote Environment Settings]
# These settings can be configured to adapt Jupyter-O2 to an environment other than O2.
Expand Down
6 changes: 3 additions & 3 deletions src/jupyter_o2/jupyter_o2.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def login(self, server, username=None, password="", code=None, *args, **kwargs):
new_args = dict(
sync_original_prompt=False,
auto_prompt_reset=False,
original_prompt=f"[#$]|{self.duo_pattern}",
original_prompt=f"[$]|{self.duo_pattern}",
)
if kwargs:
kwargs.update(new_args)
Expand Down Expand Up @@ -95,11 +95,11 @@ def login(self, server, username=None, password="", code=None, *args, **kwargs):
self._buffer = self.buffer_type()
if code is not None:
self.sendline(code)
i = self.expect(["[#$]", self.duo_pattern])
i = self.expect(["$", self.duo_pattern])
logger.debug(f"Found prompt #{i}")
if i == 1: # search for prompt one more time
self.sendline()
i = self.expect(["[#$]", self.duo_pattern])
i = self.expect(["$", self.duo_pattern])
logger.debug(f"Found prompt #{i}")
if i == 1:
self.close()
Expand Down
40 changes: 27 additions & 13 deletions src/jupyter_o2/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import logging
from time import sleep
import subprocess
import signal
import shlex
import ast

Expand Down Expand Up @@ -100,11 +101,8 @@ def try_quit_xquartz():
print("Quitting XQuartz... ", end="")
open_windows = get_xquartz_open_windows()
if open_windows is None:
logger.warning(
"Quitting XQuartz is not supported. "
"Import pyobjc-framework-Quartz with pip."
)
elif not open_windows:
pass
elif len(open_windows) < 2:
quit_xquartz()
else:
print("\nXQuartz window(s) are open. Not quitting.")
Expand Down Expand Up @@ -135,28 +133,44 @@ def get_xquartz_open_windows():
Requires pyobjc-framework-Quartz (install with pip)
:return: a list of open windows as python dictionaries
"""
# pyobjc-framework-Quartz can segfault if the wrong version is installed
logger = logging.getLogger(__name__)
p = subprocess.Popen([sys.executable, "-c", "import Quartz"])
p.communicate()
if p.returncode == -signal.SIGSEGV:
logger.warning(
"Import of pyobjc-framework-Quartz failed due to a segmentation fault. "
"The installed version is incompatible with your system."
)
return None

try:
from Quartz import (
CGWindowListCopyWindowInfo,
kCGWindowListOptionAll,
kCGWindowListExcludeDesktopElements,
kCGNullWindowID,
)
from PyObjCTools import Conversion
except ImportError:
return None
# need to use kCGWindowListOptionAll to include windows
# that are not currently on screen (e.g. minimized)
windows = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID)
logger.warning(
"Import of pyobjc-framework-Quartz failed. Try installing with pip."
)
# need to use kCGWindowListExcludeDesktopElements to include windows
# that are not currently on screen (e.g. minimized).
# kCGWindowListExcludeDesktopElements | kCGWindowListOptionOnScreenOnly
# will exclude minimized windows. Use KEEP_XQUARTZ if this is an issue.
windows = CGWindowListCopyWindowInfo(
kCGWindowListExcludeDesktopElements, kCGNullWindowID
)

# then filter for XQuartz main windows
open_windows = [
window
for window in windows
if window["kCGWindowOwnerName"] == "XQuartz"
and window["kCGWindowLayer"] == 0
and "kCGWindowName" in window.keys()
and window["kCGWindowName"]
not in ["", "X11 Application Menu", "X11 Preferences"]
and window["kCGWindowBounds"]["X"] != 0
and window["kCGWindowBounds"]["Y"] != 0
]

# convert from NSDictionary to python dictionary
Expand Down

0 comments on commit 3e4fc51

Please sign in to comment.