mirror of
https://github.com/GNS3/gns3-gui.git
synced 2026-06-28 21:27:17 +03:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e50c2a4b1 | ||
|
|
94c636ae61 | ||
|
|
f53b9a266e | ||
|
|
2476448032 | ||
|
|
a34cd742e3 | ||
|
|
39698196ac | ||
|
|
61432ced4f | ||
|
|
2ddd13c445 | ||
|
|
af6c4c5b3e | ||
|
|
d4012294bf | ||
|
|
4b04b0e855 | ||
|
|
1bec5019bf | ||
|
|
ec6b876baa | ||
|
|
7cee0d01ab | ||
|
|
dd3314d06b | ||
|
|
9c58b26265 | ||
|
|
83c26f47da | ||
|
|
8ed2f55600 | ||
|
|
b435317904 | ||
|
|
acb8aa8ca2 | ||
|
|
c55d6b8a6f | ||
|
|
a4039a254e | ||
|
|
85ed4b3026 | ||
|
|
5207a99692 | ||
|
|
d69527995d | ||
|
|
4b000ba2f7 | ||
|
|
1b302b77a0 | ||
|
|
a5b5c404ec | ||
|
|
6b97b0c6cd | ||
|
|
115dd43eee |
19
.github/workflows/testing.yml
vendored
Normal file
19
.github/workflows/testing.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: testing
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build and run Docker image
|
||||
run: |
|
||||
docker build -t gns3-gui-test .
|
||||
docker run gns3-gui-test
|
||||
21
.travis.yml
21
.travis.yml
@@ -1,21 +0,0 @@
|
||||
sudo: required
|
||||
services:
|
||||
- docker
|
||||
notifications:
|
||||
email: false
|
||||
script:
|
||||
- docker build -t gns3-gui-test .
|
||||
- docker run gns3-gui-test
|
||||
before_deploy:
|
||||
- sudo pip install twine
|
||||
- sudo pip install urllib3[secure]
|
||||
deploy:
|
||||
provider: pypi
|
||||
edge:
|
||||
branch: v1.8.45
|
||||
user: noplay
|
||||
password:
|
||||
secure: FofcqlJjgqf2jaDaXpLHeigVoexbrOz3WwnDuiJpwJxeFUlPY8s2cQs/Bm+dzxzZaOaGiVE0A83v/Xa10yD5tflThHt4sqYJK3iQCinA7wgeAlDimB4xrWUNplfNJZ/Eod5Ssa++E02W+3i29PxpXY//mjCY7qDxaoxul1gnFJY=
|
||||
on:
|
||||
tags: true
|
||||
repo: GNS3/gns3-gui
|
||||
13
.whitesource
Normal file
13
.whitesource
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"scanSettings": {
|
||||
"configMode": "AUTO",
|
||||
"configExternalURL": "",
|
||||
"projectToken" : ""
|
||||
},
|
||||
"checkRunSettings": {
|
||||
"vulnerableCheckRunConclusionLevel": "failure"
|
||||
},
|
||||
"issueSettings": {
|
||||
"minSeverityLevel": "LOW"
|
||||
}
|
||||
}
|
||||
16
CHANGELOG
16
CHANGELOG
@@ -1,5 +1,21 @@
|
||||
# Change Log
|
||||
|
||||
## 2.2.11 09/07/2020
|
||||
|
||||
* Try to fix "Recent project" selection not working. Ref #3007
|
||||
* Fix debug entries shown twice in console window and double error messages with remote GNS3VM. Fixes #3010
|
||||
* Fix deprecation warning. Ref #3009
|
||||
* Fix tests on macOS. Ref #3009
|
||||
* Fix sentry SDK is configured twice.
|
||||
|
||||
## 2.2.10 18/06/2020
|
||||
|
||||
* New fix for multi-device selection/deselection not working as expected with right click. Fixes #2986
|
||||
* Optimize snap-to-grid code for drawing items. Fixes #2997
|
||||
* Move jsonschema 2.6.0 requirement in build repository.
|
||||
* Only use jsonschema 2.6.0 on Windows and macOS.
|
||||
* Disable default integrations for sentry sdk.
|
||||
|
||||
## 2.2.9 04/06/2020
|
||||
|
||||
* Fix GUI doesn't detect another GUI on macOS. Fixes #2994
|
||||
|
||||
@@ -1,22 +1,16 @@
|
||||
# Run tests inside a container
|
||||
FROM ubuntu:18.04
|
||||
|
||||
MAINTAINER GNS3 Team
|
||||
|
||||
#ENV DEBIAN_FRONTEND noninteractive
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y --force-yes python3.6 python3-pyqt5 python3-pip python3-pyqt5.qtsvg python3-pyqt5.qtwebsockets python3.6-dev xvfb
|
||||
RUN apt-get clean
|
||||
|
||||
|
||||
ADD dev-requirements.txt /dev-requirements.txt
|
||||
ADD requirements.txt /requirements.txt
|
||||
RUN pip3 install -r /dev-requirements.txt
|
||||
|
||||
|
||||
ADD . /src
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
CMD xvfb-run python3.6 -m pytest -vv
|
||||
|
||||
@@ -3,7 +3,6 @@ include AUTHORS
|
||||
include LICENSE
|
||||
include MANIFEST.in
|
||||
include requirements.txt
|
||||
include tox.ini
|
||||
recursive-include tests *
|
||||
recursive-include gns3 *
|
||||
recursive-include resources *
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
GNS3-gui
|
||||
========
|
||||
|
||||
.. image:: https://travis-ci.org/GNS3/gns3-gui.svg?branch=master
|
||||
:target: https://travis-ci.org/GNS3/gns3-gui
|
||||
.. image:: https://github.com/GNS3/gns3-gui/workflows/testing/badge.svg
|
||||
:target: https://github.com/GNS3/gns3-gui/actions?query=workflow%3Atesting
|
||||
|
||||
.. image:: https://img.shields.io/pypi/v/gns3-gui.svg
|
||||
:target: https://pypi.python.org/pypi/gns3-gui
|
||||
|
||||
.. image:: https://snyk.io/test/github/GNS3/gns3-gui/badge.svg
|
||||
:target: https://snyk.io/test/github/GNS3/gns3-gui
|
||||
|
||||
|
||||
GNS3 GUI repository.
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
-rrequirements.txt
|
||||
|
||||
pep8==1.7.0
|
||||
pytest==4.4.1
|
||||
pytest-pythonpath==0.7.3 # useful for running tests outside tox
|
||||
pytest-timeout==1.3.3
|
||||
pytest==5.4.3
|
||||
flake8==3.8.3
|
||||
pytest-timeout==1.4.1
|
||||
|
||||
@@ -223,17 +223,10 @@ class ConsoleCmd(cmd.Cmd):
|
||||
level = int(args[0])
|
||||
if level == 0:
|
||||
print("Deactivating debugging")
|
||||
for handler in root.handlers:
|
||||
if isinstance(handler, logging.StreamHandler):
|
||||
root.removeHandler(handler)
|
||||
root.setLevel(logging.INFO)
|
||||
else:
|
||||
root.addHandler(logging.StreamHandler(sys.stdout))
|
||||
if level == 1:
|
||||
print("Activating debugging")
|
||||
else:
|
||||
print("Activating full debugging")
|
||||
root.setLevel(logging.DEBUG)
|
||||
print("Activating debugging")
|
||||
root.setLevel(logging.DEBUG)
|
||||
from .main_window import MainWindow
|
||||
MainWindow.instance().setSettings({"debug_level": level})
|
||||
else:
|
||||
|
||||
@@ -51,7 +51,7 @@ class CrashReport:
|
||||
Report crash to a third party service
|
||||
"""
|
||||
|
||||
DSN = "https://1a54ce2e5db84c5caa3bd1ad9ab5dd37:6fc7b3f8deca4a1ebf2f551b310e9b3f@o19455.ingest.sentry.io/38506"
|
||||
DSN = "https://2bd594d79ae248d38422b43a914abc4f:cd35061ce69c4fc99c4dc9e195087512@o19455.ingest.sentry.io/38506"
|
||||
_instance = None
|
||||
|
||||
def __init__(self):
|
||||
@@ -78,12 +78,9 @@ class CrashReport:
|
||||
sentry_sdk.init(dsn=CrashReport.DSN,
|
||||
release=__version__,
|
||||
ca_certs=cacert,
|
||||
default_integrations=False,
|
||||
integrations=[sentry_logging])
|
||||
|
||||
sentry_sdk.init(dsn=CrashReport.DSN,
|
||||
release=__version__,
|
||||
ca_certs=cacert)
|
||||
|
||||
tags = {
|
||||
"os:name": platform.system(),
|
||||
"os:release": platform.release(),
|
||||
|
||||
@@ -237,13 +237,13 @@ class ProjectDialog(QtWidgets.QDialog, Ui_ProjectDialog):
|
||||
"""
|
||||
|
||||
menu = QtWidgets.QMenu()
|
||||
menu.triggered.connect(self._menuTriggeredSlot)
|
||||
if Controller.instance().isRemote():
|
||||
for action in self._main_window.recent_project_actions:
|
||||
menu.addAction(action)
|
||||
else:
|
||||
for action in self._main_window.recent_file_actions:
|
||||
menu.addAction(action)
|
||||
menu.triggered.connect(self._menuTriggeredSlot)
|
||||
menu.exec_(QtGui.QCursor.pos())
|
||||
|
||||
def _overwriteProjectCallback(self, result, error=False, **kwargs):
|
||||
|
||||
@@ -527,13 +527,12 @@ class GraphicsView(QtWidgets.QGraphicsView):
|
||||
|
||||
if is_not_link and is_not_logo and not self._adding_link:
|
||||
if item and not sip.isdeleted(item):
|
||||
# Right clicking on a selected item must de-select all other items
|
||||
# excepting if CRTL is pressed
|
||||
item.setSelected(True)
|
||||
if not event.modifiers() & QtCore.Qt.ControlModifier:
|
||||
for it in self.scene().items():
|
||||
if item != it and it.isSelected():
|
||||
# Prevent right clicking on a selected item from de-selecting all other items
|
||||
if not item.isSelected():
|
||||
if not event.modifiers() & QtCore.Qt.ControlModifier:
|
||||
for it in self.scene().items():
|
||||
it.setSelected(False)
|
||||
item.setSelected(True)
|
||||
self._showDeviceContextualMenu(event.globalPos())
|
||||
# when more than one item is selected display the contextual menu even if mouse is not above an item
|
||||
elif len(self.scene().selectedItems()) > 1:
|
||||
@@ -755,6 +754,11 @@ class GraphicsView(QtWidgets.QGraphicsView):
|
||||
self.populateDeviceContextualMenu(menu)
|
||||
menu.exec_(pos)
|
||||
menu.clear()
|
||||
# Make sure to deselect all items.
|
||||
# This is to prevent a bug on Windows
|
||||
# see https://github.com/GNS3/gns3-gui/issues/2986
|
||||
for it in self.scene().items():
|
||||
it.setSelected(False)
|
||||
|
||||
def populateDeviceContextualMenu(self, menu):
|
||||
"""
|
||||
|
||||
@@ -212,14 +212,13 @@ class DrawingItem:
|
||||
self._project.delete("/drawings/" + self._id, None, body=self.__json__())
|
||||
|
||||
def itemChange(self, change, value):
|
||||
if change == QtWidgets.QGraphicsItem.ItemPositionHasChanged and self.isActive() and self._main_window.uiSnapToGridAction.isChecked():
|
||||
|
||||
if change == QtWidgets.QGraphicsItem.ItemPositionChange and self.isActive() and self._main_window.uiSnapToGridAction.isChecked():
|
||||
grid_size = self._graphics_view.drawingGridSize()
|
||||
mid_x = self.boundingRect().width() / 2
|
||||
tmp_x = (grid_size * round((self.x() + mid_x) / grid_size)) - mid_x
|
||||
value.setX((grid_size * round((value.x() + mid_x) / grid_size)) - mid_x)
|
||||
mid_y = self.boundingRect().height() / 2
|
||||
tmp_y = (grid_size * round((self.y() + mid_y) / grid_size)) - mid_y
|
||||
if tmp_x != self.x() and tmp_y != self.y():
|
||||
self.setPos(tmp_x, tmp_y)
|
||||
value.setY((grid_size * round((value.y()+mid_y)/grid_size)) - mid_y)
|
||||
|
||||
if change == QtWidgets.QGraphicsItem.ItemSelectedChange:
|
||||
if not value:
|
||||
|
||||
@@ -1185,8 +1185,9 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
||||
|
||||
# restore debug level
|
||||
if self._settings["debug_level"]:
|
||||
print("Activating debugging (use command 'debug 0' to deactivate)")
|
||||
root = logging.getLogger()
|
||||
root.addHandler(logging.StreamHandler(sys.stdout))
|
||||
root.setLevel(logging.DEBUG)
|
||||
|
||||
# restore the style
|
||||
self._setStyle(self._settings.get("style"))
|
||||
|
||||
@@ -115,10 +115,13 @@ class LogQMessageBox(QtWidgets.QMessageBox):
|
||||
show a stack trace when a critical message box is shown in debug mode
|
||||
"""
|
||||
@staticmethod
|
||||
def critical(parent, title, message, *args):
|
||||
def critical(parent, title, message, *args, show_stack_info=False):
|
||||
if message.startswith("QXcbConnection"): # Qt noise not relevant
|
||||
return
|
||||
LogQMessageBox._get_logger().critical(re.sub(r"<[^<]+?>", "", message), stack_info=LogQMessageBox.stack_info())
|
||||
stack_info = None
|
||||
if show_stack_info:
|
||||
stack_info = LogQMessageBox.stack_info()
|
||||
LogQMessageBox._get_logger().critical(re.sub(r"<[^<]+?>", "", message), stack_info=stack_info)
|
||||
if parent is False:
|
||||
# special case to display a QMessageBox before the main window is created.
|
||||
parent = None
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import json
|
||||
import copy
|
||||
import os
|
||||
import collections
|
||||
import collections.abc
|
||||
import jsonschema
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class ApplianceError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Appliance(collections.Mapping):
|
||||
class Appliance(collections.abc.Mapping):
|
||||
|
||||
def __init__(self, registry, path):
|
||||
"""
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
# or negative for a release candidate or beta (after the base version
|
||||
# number has been incremented)
|
||||
|
||||
__version__ = "2.2.9"
|
||||
__version_info__ = (2, 2, 9, 0)
|
||||
__version__ = "2.2.11"
|
||||
__version_info__ = (2, 2, 11, 0)
|
||||
|
||||
# If it's a git checkout try to add the commit
|
||||
if "dev" in __version__:
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
-rrequirements.txt
|
||||
|
||||
#PyQt5==5.7
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
jsonschema==3.2.0; python_version >= '3.8' # pyup: ignore
|
||||
jsonschema==2.6.0; python_version < '3.8' # pyup: ignore
|
||||
jsonschema==3.2.0
|
||||
sentry-sdk>=0.14.4
|
||||
psutil==5.6.6
|
||||
psutil==5.7.0
|
||||
distro>=1.3.0
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo '
|
||||
_______ ________ _______ ______
|
||||
| \ | \| \ / \
|
||||
| $$$$$$$\| $$$$$$$$| $$$$$$$\| $$$$$$\
|
||||
| $$__/ $$| $$__ | $$__/ $$| $$__/ $$
|
||||
| $$ $$| $$ \ | $$ $$ >$$ $$
|
||||
| $$$$$$$ | $$$$$ | $$$$$$$ | $$$$$$
|
||||
| $$ | $$_____ | $$ | $$__/ $$
|
||||
| $$ | $$ \| $$ \$$ $$
|
||||
\$$ \$$$$$$$$ \$$ \$$$$$$
|
||||
|
||||
'
|
||||
|
||||
|
||||
find . -name '*.py' -exec autopep8 --in-place -v --aggressive --aggressive \{\} \;
|
||||
|
||||
echo "It's clean"
|
||||
12
setup.py
12
setup.py
@@ -24,7 +24,7 @@ if len(sys.argv) >= 2 and sys.argv[1] == "install" and sys.version_info < (3, 4)
|
||||
raise SystemExit("Python 3.4 or higher is required")
|
||||
|
||||
|
||||
class Tox(TestCommand):
|
||||
class PyTest(TestCommand):
|
||||
|
||||
def finalize_options(self):
|
||||
TestCommand.finalize_options(self)
|
||||
@@ -33,10 +33,10 @@ class Tox(TestCommand):
|
||||
|
||||
def run_tests(self):
|
||||
# import here, cause outside the eggs aren't loaded
|
||||
import tox
|
||||
errcode = tox.cmdline(self.test_args)
|
||||
sys.exit(errcode)
|
||||
import pytest
|
||||
|
||||
errcode = pytest.main(self.test_args)
|
||||
sys.exit(errcode)
|
||||
|
||||
if sys.platform.startswith('linux'):
|
||||
data_files = [
|
||||
@@ -61,8 +61,8 @@ setup(
|
||||
version=__import__("gns3").__version__,
|
||||
url="http://github.com/GNS3/gns3-gui",
|
||||
license="GNU General Public License v3 (GPLv3)",
|
||||
tests_require=["tox"],
|
||||
cmdclass={"test": Tox},
|
||||
tests_require=["pytest"],
|
||||
cmdclass={"test": PyTest},
|
||||
author="Jeremy Grossmann",
|
||||
author_email="package-maintainer@gns3.net",
|
||||
description="GNS3 graphical interface for the GNS3 server.",
|
||||
|
||||
@@ -22,6 +22,7 @@ import json
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
from gns3.local_config import LocalConfig
|
||||
from gns3.version import __version_info__
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -119,16 +120,17 @@ def test_migrateOldConfigOSX(tmpdir):
|
||||
|
||||
local_config = LocalConfig()
|
||||
|
||||
assert os.path.exists(str(tmpdir / '.config' / 'GNS3'))
|
||||
assert os.path.exists(str(tmpdir / '.config' / 'GNS3' / 'hello'))
|
||||
version = "{}.{}".format(__version_info__[0], __version_info__[1])
|
||||
assert os.path.exists(str(tmpdir / '.config' / 'GNS3' / version))
|
||||
assert os.path.exists(str(tmpdir / '.config' / 'GNS3' / version / 'hello'))
|
||||
assert os.path.exists(str(tmpdir / '.config' / 'gns3.net'))
|
||||
|
||||
# It should migrate only one time
|
||||
open(str(tmpdir / '.config' / 'gns3.net' / 'world'), 'w+').close()
|
||||
|
||||
local_config._migrateOldConfigPath()
|
||||
assert os.path.exists(str(tmpdir / '.config' / 'GNS3' / 'hello'))
|
||||
assert not os.path.exists(str(tmpdir / '.config' / 'GNS3' / 'world'))
|
||||
assert os.path.exists(str(tmpdir / '.config' / 'GNS3' / version / 'hello'))
|
||||
assert not os.path.exists(str(tmpdir / '.config' / 'GNS3' / version / 'world'))
|
||||
|
||||
|
||||
def test_migrate13Config(tmpdir):
|
||||
|
||||
19
tox.ini
19
tox.ini
@@ -1,19 +0,0 @@
|
||||
[tox]
|
||||
envlist = py34
|
||||
|
||||
[testenv]
|
||||
sitepackages=True
|
||||
setenv = PYTHONPATH={toxinidir}
|
||||
commands = py.test
|
||||
|
||||
[pep8]
|
||||
ignore = E501,E402
|
||||
|
||||
[flake8]
|
||||
ignore = E265,E501
|
||||
exclude = tests/*,gns3/ui/*,./gns3/modules/*/ui
|
||||
|
||||
[pytest]
|
||||
python_paths = {toxinidir}
|
||||
norecursedirs = .tox
|
||||
timeout = 10
|
||||
Reference in New Issue
Block a user