Skip to content

Commit

Permalink
Merge pull request #7 from DazEdword/feature/downloads-accepting-vpn-…
Browse files Browse the repository at this point in the history
…check-and-connect

Feature/downloads accepting vpn check and connect
  • Loading branch information
DazEdword authored Nov 9, 2019
2 parents 7d66c10 + 89b01a6 commit de0f145
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.3.17
current_version = 0.4.0
commit = True
tag = True

Expand Down
3 changes: 3 additions & 0 deletions .isort.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[settings]
multi_line_output=3
include_trailing_comma=True
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="synotools",
version="0.3.17",
version="0.4.0",
author="Ed Garabito",
author_email="eduardo@gottabegarabi.com",
description="A Python API wrapper and toolset to interact with Synology NAS devices.",
Expand Down
31 changes: 24 additions & 7 deletions synotools/commands/download.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import sys
import argparse

from fabric import Config, Connection

from synotools.commands.vpn_connect import check_and_connect
from synotools.common.logging import get_logger
from synotools.models.config import DelugeConfig, SynoConfig

logger = get_logger(__name__)


def download_torrent_with_deluge(torrent_url):
def download_torrent_with_deluge(torrent_url, skip_vpn=False):
if skip_vpn:
logger.info("Skipping VPN checks...")
else:
check_and_connect()

logger.debug("Creating config files...")
syno_config = SynoConfig()
deluge_config = DelugeConfig()
Expand Down Expand Up @@ -38,9 +44,20 @@ def download_torrent_with_deluge(torrent_url):
if __name__ == "__main__":
torrent_url = None

try:
torrent_url = sys.argv[1]
except IndexError:
pass
parser = argparse.ArgumentParser(description="Download torrent with Deluge.")
parser.add_argument(
"torrent_url", type=str, help="the torrent url or magnet to download"
)
parser.add_argument(
"--no-vpn",
dest="no_vpn",
action="store_true",
help="skip vpn check and/or vpn connection (if disabled)",
required=False,
)

args = parser.parse_args()
torrent_url = args.torrent_url
no_vpn = args.no_vpn

download_torrent_with_deluge(torrent_url)
download_torrent_with_deluge(torrent_url, no_vpn)
10 changes: 6 additions & 4 deletions synotools/commands/vpn_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@ def check_and_connect():
vpn_connected = is_vpn_enabled(connection)

if not vpn_connected:
connect_vpn(connection)
vpn_connected = connect_vpn(connection)

return vpn_connected


def is_vpn_enabled(connection):
try:
command = ".scripts/vpn-check-connection.sh"
vpn_check_result = connection.sudo(command, warn=True)
logger.info(vpn_check_result)
except Exception as e:
logger.error(f"An error occurred: {e}")
except Exception:
logger.exception(f"An error occurred.")
raise

return (
Expand All @@ -44,7 +46,7 @@ def connect_vpn(connection):
try:
command = f".scripts/vpn-connect.sh {params}"
vpn_connect_result = connection.sudo(command, warn=True)
logger.info(vpn_connect_result)
return vpn_connect_result.ok
except Exception as e:
logger.error(f"An error occurred: {e}")
raise
Expand Down
49 changes: 47 additions & 2 deletions tests/unit/command/download/test_download_torrent_with_deluge.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from unittest.mock import patch

from synotools.commands.download import download_torrent_with_deluge
from tests.unit.fixtures import (create_deluge_config_mock,
create_syno_config_mock)
from tests.unit.fixtures import (
create_deluge_config_mock,
create_syno_config_mock,
)

TORRENT_URL = "https://www.archlinux.org/releng/releases/2019.06.01/torrent/"


@patch("synotools.commands.download.check_and_connect")
@patch("synotools.commands.download.Connection")
@patch(
"synotools.commands.download.DelugeConfig", return_value=create_deluge_config_mock()
Expand All @@ -17,6 +20,7 @@ def test_gets_synology_config_details(syno_config_mock, deluge_config_mock, *_):
syno_config_mock.assert_called_once()


@patch("synotools.commands.download.check_and_connect")
@patch("synotools.commands.download.Connection")
@patch("synotools.commands.download.SynoConfig", return_value=create_syno_config_mock())
@patch(
Expand All @@ -27,6 +31,7 @@ def test_gets_deluge_config_details(deluge_config_mock, *_):
deluge_config_mock.assert_called_once()


@patch("synotools.commands.download.check_and_connect")
@patch("synotools.commands.download.get_logger")
@patch(
"synotools.commands.download.DelugeConfig", return_value=create_deluge_config_mock()
Expand All @@ -44,6 +49,7 @@ def test_creates_fabric_connection_with_correct_sudo_config(
)


@patch("synotools.commands.download.check_and_connect")
@patch("synotools.commands.download.logger")
@patch(
"synotools.commands.download.DelugeConfig", return_value=create_deluge_config_mock()
Expand All @@ -63,6 +69,7 @@ def test_creates_fabric_connection_with_correct_credentials(
connection_mock.return_value.sudo.assert_called_once_with(expected_command)


@patch("synotools.commands.download.check_and_connect")
@patch(
"synotools.commands.download.DelugeConfig", return_value=create_deluge_config_mock()
)
Expand All @@ -80,3 +87,41 @@ def test_logs_message_when_exception_occurs(connection_mock, logger_mock, *_):
logger_mock.error.assert_called_once_with(
f"An error occurred: Uh oh, something happened!"
)


@patch(
"synotools.commands.download.DelugeConfig", return_value=create_deluge_config_mock()
)
@patch("synotools.commands.download.SynoConfig", return_value=create_syno_config_mock())
@patch("synotools.commands.download.Config")
@patch("synotools.commands.download.check_and_connect")
@patch("synotools.commands.download.logger")
@patch("synotools.commands.download.Connection")
def test_skips_vpn_checks_when_flag_is_passed(
connection_mock, logger_mock, check_and_connect_mock, *_
):

# Act
download_torrent_with_deluge(TORRENT_URL, True)

# Assert
assert not check_and_connect_mock.called


@patch(
"synotools.commands.download.DelugeConfig", return_value=create_deluge_config_mock()
)
@patch("synotools.commands.download.SynoConfig", return_value=create_syno_config_mock())
@patch("synotools.commands.download.Config")
@patch("synotools.commands.download.check_and_connect")
@patch("synotools.commands.download.logger")
@patch("synotools.commands.download.Connection")
def test_checks_and_connects_vpn_by_default(
connection_mock, logger_mock, check_and_connect_mock, *_
):

# Act
download_torrent_with_deluge(TORRENT_URL)

# Assert
assert check_and_connect_mock.called
45 changes: 45 additions & 0 deletions tests/unit/command/vpn_connect/test_check_and_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,48 @@ def test_connects_if_check_retrieves_it_is_not_connected(
check_and_connect()

connect_vpn_mock.assert_called_once_with(connection_mock.return_value)


@patch("synotools.commands.vpn_connect.logger")
@patch(
"synotools.commands.vpn_connect.SynoConfig", return_value=create_syno_config_mock()
)
@patch("synotools.commands.vpn_connect.Config")
@patch("synotools.commands.vpn_connect.connect_vpn")
@patch("synotools.commands.vpn_connect.is_vpn_enabled")
@patch("synotools.commands.vpn_connect.Connection")
def test_returns_true_when_vpn_is_already_connected(
connection_mock, is_vpn_enabled_mock, connect_vpn_mock, *_
):
# Arrange
is_vpn_enabled_mock.return_value = True

# Act
actual = check_and_connect()

# Assert
assert actual is True
assert not connect_vpn_mock.called


@patch("synotools.commands.vpn_connect.logger")
@patch(
"synotools.commands.vpn_connect.SynoConfig", return_value=create_syno_config_mock()
)
@patch("synotools.commands.vpn_connect.Config")
@patch("synotools.commands.vpn_connect.connect_vpn")
@patch("synotools.commands.vpn_connect.is_vpn_enabled")
@patch("synotools.commands.vpn_connect.Connection")
def test_returns_true_when_vpn_is_attempted_to_connect_and_succeeds(
connection_mock, is_vpn_enabled_mock, connect_vpn_mock, *_
):
# Arrange
is_vpn_enabled_mock.return_value = False
connect_vpn_mock.return_value = True

# Act
actual = check_and_connect()

# Assert
assert actual is True
connect_vpn_mock.assert_called_once_with(connection_mock.return_value)
32 changes: 32 additions & 0 deletions tests/unit/command/vpn_connect/test_connect_vpn.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,35 @@ def test_logs_error_ans_raises_exception_when_fabric_process_fails(logger_mock,
connect_vpn(connection_mock)

logger_mock.error.assert_called_once_with("An error occurred: Hah! Didn't work.")


@patch(
"synotools.commands.vpn_connect.VpnConfig", return_value=create_vpn_config_fake()
)
@patch("synotools.commands.vpn_connect.logger")
def test_returns_true_when_remote_script_succeeds(logger_mock, *_):
# Arrange
connection_mock = Mock()
connection_mock.sudo.return_value = Mock(ok=True)

# Act
actual = connect_vpn(connection_mock)

# Assert
assert actual is True


@patch(
"synotools.commands.vpn_connect.VpnConfig", return_value=create_vpn_config_fake()
)
@patch("synotools.commands.vpn_connect.logger")
def test_returns_false_when_remote_script_fails(logger_mock, *_):
# Arrange
connection_mock = Mock()
connection_mock.sudo.return_value = Mock(ok=False)

# Act
actual = connect_vpn(connection_mock)

# Assert
assert actual is False

0 comments on commit de0f145

Please sign in to comment.