Skip to content

Commit

Permalink
Merge branch '1.0.x' into 'master'
Browse files Browse the repository at this point in the history
  • Loading branch information
remram44 committed Oct 6, 2016
2 parents 7a2395d + 10c1551 commit 6e933ca
Show file tree
Hide file tree
Showing 17 changed files with 705 additions and 260 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Bugfixes:
* Fix an issue identifying Debian packages when a file's in two packages
* Fix Python error `Mixing iteration and read methods would lose data`
* Fix reprounzip info showing some numbers as 0 instead of hiding them in non-verbose mode
* Another fix to X server IP determination for Docker

Enhancements:
* New GUI for reprounzip, allowing one to unpack without using the command-line
Expand Down
51 changes: 31 additions & 20 deletions reprounzip-docker/reprounzip/unpackers/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,33 +325,44 @@ def get_local_addr():
>>> get_local_addr()
'172.17.42.1'
"""
# This function works by creating a socket and connecting to a remote IP.
# The local address of this socket is assumed to be the address of this
# machine, that the Docker container can reach.
target = None

# Find hostname or IP address in DOCKER_HOST
if 'DOCKER_HOST' in os.environ:
m = _addr_re.match(os.environ['DOCKER_HOST'])
if m is not None:
ip = m.group(1)
target = m.group(1)
if target.startswith('127.'):
target = None

# Else, use whatever local interface lets you connect to google.com
if target is None:
target = 'google.com'

try:
addresses = socket.getaddrinfo(target, 9, socket.AF_UNSPEC,
socket.SOCK_STREAM)
except socket.gaierror:
pass
else:
for address in addresses:
sock = None
try:
addresses = socket.getaddrinfo(ip, 9, socket.AF_UNSPEC,
socket.SOCK_STREAM)
except socket.gaierror:
af, socktype, proto, canonname, sa = address
sock = socket.socket(af, socktype, proto)
sock.settimeout(1)
sock.connect(sa)
sock.close()
except socket.error:
pass
else:
for address in addresses:
sock = None
try:
af, socktype, proto, canonname, sa = address
sock = socket.socket(af, socktype, proto)
sock.settimeout(1)
sock.connect(sa)
sock.close()
except socket.error:
pass
if sock is not None:
addr = sock.getsockname()[0]
if isinstance(addr, bytes):
addr = addr.decode('ascii')
return addr
if sock is not None:
addr = sock.getsockname()[0]
if isinstance(addr, bytes):
addr = addr.decode('ascii')
return addr

return '127.0.0.1'

Expand Down
27 changes: 27 additions & 0 deletions reprounzip-qt/reprounzip_qt/gui/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright (C) 2014-2016 New York University
# This file is part of ReproZip which is released under the Revised BSD License
# See file LICENSE for full license details.

from __future__ import division, print_function, unicode_literals

from PyQt4 import QtGui

from reprounzip_qt.gui.unpack import UnpackTab
from reprounzip_qt.gui.run import RunTab


class ReprounzipUi(QtGui.QMainWindow):
def __init__(self, unpack={}, run={}, tab=None, **kwargs):
super(ReprounzipUi, self).__init__(**kwargs)

self.tabs = QtGui.QTabWidget()
self.tabs.addTab(UnpackTab(**unpack), "Open package")
self.tabs.addTab(RunTab(**run), "Run unpacked experiment")
self.tabs.widget(0).unpacked.connect(self._unpacked)
if tab is not None:
self.tabs.setCurrentIndex(tab)
self.setCentralWidget(self.tabs)

def _unpacked(self, directory, root):
self.tabs.widget(1).set_directory(directory, root=root)
self.tabs.setCurrentIndex(1)
55 changes: 55 additions & 0 deletions reprounzip-qt/reprounzip_qt/gui/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright (C) 2014-2016 New York University
# This file is part of ReproZip which is released under the Revised BSD License
# See file LICENSE for full license details.

from __future__ import division, print_function, unicode_literals

from PyQt4 import QtCore, QtGui


def error_msg(parent, message, severity, details=None):
if severity == 'information':
icon = QtGui.QMessageBox.Information
elif severity == 'warning':
icon = QtGui.QMessageBox.Warning
else:
icon = QtGui.QMessageBox.Critical

msgbox = QtGui.QMessageBox(icon, "Error", message, QtGui.QMessageBox.Ok,
parent, detailedText=details,
textFormat=QtCore.Qt.PlainText)
msgbox.exec_()


def handle_error(parent, result):
if result in (True, False):
return result
else:
error_msg(parent, *result)
return False


class ResizableStack(QtGui.QStackedWidget):
# See http://stackoverflow.com/a/14485901/711380
def __init__(self, **kwargs):
super(ResizableStack, self).__init__(**kwargs)

self.currentChanged[int].connect(self._current_changed)

def addWidget(self, widget):
widget.setSizePolicy(QtGui.QSizePolicy.Ignored,
QtGui.QSizePolicy.Ignored)
super(ResizableStack, self).addWidget(widget)

def _current_changed(self, idx):
widget = self.widget(idx)
widget.setSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
widget.adjustSize()
self.adjustSize()


class ROOT(object):
OPTION_TO_INDEX = {None: 0, 'sudo': 1, 'su': 2}
INDEX_TO_OPTION = {0: None, 1: 'sudo', 2: 'su'}
TEXT = ["no", "with sudo", "with su"]

0 comments on commit 6e933ca

Please sign in to comment.