Repository: phac-nml/irida-uploader

Issue:
Optional global configuration file
## Describe your idea for a new feature
Nice to have an optional  global configuration file for sequencer that may have dozen of local users. It is time consuming for each individual user to create the same configuration file.

## Additional information
Add any other context, files, or screenshots about the feature request here.


Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 736ba39..1a57bbc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,14 @@
 Changes
 =======
 
+Beta 0.3.2
+----------
+Added functionality:
+* Default config file can now be overridden across a system by adding a config.conf file to the source directory. Specifying config file from command line trumps the override file.
+
+Changes:
+* Logging directory has been changed from `irida_uploader` to `irida-uploader` to match config directory naming.
+
 Beta 0.3.1
 ----------
 Added functionality:
diff --git a/config/config.py b/config/config.py
index d749c99..aa416b9 100644
--- a/config/config.py
+++ b/config/config.py
@@ -10,6 +10,10 @@ _user_config_file = None
 
 _default_user_config_file_path = os.path.join(user_config_dir("irida-uploader"), "config.conf")
 
+# set an override config file in the source code directory, if it exists it will be used instead of getting it from user
+_override_config_file_path = os.path.realpath(os.path.join(os.path.dirname(
+    os.path.abspath(__file__)), os.path.pardir, "config.conf"))
+
 
 def set_config_file(config_file):
     """
@@ -150,16 +154,20 @@ def setup():
     global _conf_parser
     global _user_config_file
     global _default_user_config_file_path
+    global _override_config_file_path
 
     _init_config_parser()
     # If a config file is set, inform user
     if _user_config_file:
         logging.info("Config file set to {}".format(_user_config_file))
+    # if the override config file exists, use it over the default
+    elif os.path.exists(_override_config_file_path):
+        logging.info("Override config file found. Using file: {}".format(_override_config_file_path))
+        _user_config_file = _override_config_file_path
     # If a config file was not set, create a new file
     elif not os.path.exists(_default_user_config_file_path):
         logging.info("No config file found, creating a new file {}".format(_default_user_config_file_path))
         _create_new_config_file()
-
     # Use the default file as the user config file
     else:
         logging.info("Using default config file {}".format(_default_user_config_file_path))
diff --git a/core/cli_entry.py b/core/cli_entry.py
index 9563081..341a241 100644
--- a/core/cli_entry.py
+++ b/core/cli_entry.py
@@ -9,7 +9,7 @@ from model import DirectoryStatus
 
 from . import api_handler, parsing_handler, logger, exit_return
 
-VERSION_NUMBER = "0.3.1"
+VERSION_NUMBER = "0.3.2"
 
 
 def upload_run_single_entry(directory, force_upload=False):
diff --git a/core/logger.py b/core/logger.py
index c8a373f..f70d64d 100644
--- a/core/logger.py
+++ b/core/logger.py
@@ -4,7 +4,7 @@ import logging.handlers
 
 
 # Normal base logging directory name
-log_directory_name = "irida_uploader"
+log_directory_name = "irida-uploader"
 # When running tests, the Makefile creates an environment variable IRIDA_UPLOADER_TEST to 'True'
 # If it exists then we are running a test and should be logging to the test logs directory
 if os.environ.get('IRIDA_UPLOADER_TEST'):
diff --git a/docs/configuration.md b/docs/configuration.md
index 0faa61b..a4122ba 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -80,3 +80,23 @@ This can be done as given parameters `--option parameter` or via user prompt `--
                         Override "parser" in config file. Can be used without
                         a parameter to prompt for input.
 ```
+
+###Admin Config Override
+
+In some workflows it makes sense to have a single irida user account uploading for any user signed in on the sequencer machine. In this case the config override can be used to avoid having to enter the credentials for each new user.
+
+You can add your config file to the source code directory and the uploader will prioritize it over the default user config file.
+
+Note: Specifying the config file with the `--config` option takes priority over the override config file.
+
+#### Windows file location
+
+First, when installing the uploader, make sure to install for all users.
+
+The config file can be placed in the install directories `pkgs` folder. The default is:
+
+`C:\Program Files (x86)\IRIDA Sequence Uploader GUI\pkgs`
+
+#### Linux file location
+
+The config file can be placed into the root directory of the source code: `irida-uploader/`
diff --git a/docs/index.md b/docs/index.md
index 31321ae..2336e7d 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -157,11 +157,11 @@ Full debug logs are written to your system default logging directory
 
 #### Linux
 
-`/home/<user>/.cache/irida_uploader/log/`
+`/home/<user>/.cache/irida-uploader/log/`
 
 #### Windows
 
-`C:\Users\<username>\AppData\Local\irida_uploader\irida_uploader\Logs`
+`C:\Users\<username>\AppData\Local\irida-uploader\irida-uploader\Logs`
 
 # Problems?
 
diff --git a/upload_gui.py b/upload_gui.py
index e8e0417..88f5be3 100644
--- a/upload_gui.py
+++ b/upload_gui.py
@@ -11,7 +11,7 @@ import traceback
 
 def get_crash_log_file_path():
     # Normal base logging directory name
-    log_directory_name = "irida_uploader"
+    log_directory_name = "irida-uploader"
     # Use systems default logging path, and append our named directory
     log_file_path = os.path.join(user_log_dir(log_directory_name), 'crash.log')
     # Create the directory if it doesn't exist
diff --git a/windows-gui-installer.cfg b/windows-gui-installer.cfg
index bea2223..9fa4fba 100644
--- a/windows-gui-installer.cfg
+++ b/windows-gui-installer.cfg
@@ -1,6 +1,6 @@
 [Application]
 name=IRIDA Sequence Uploader GUI
-version=0.3.1
+version=0.3.2
 entry_point=upload_gui:main
 icon=gui/images/icon.ico
 # Uncomment this to have a console show alongside the application
diff --git a/windows-installer.cfg b/windows-installer.cfg
index 70f2eaf..776e451 100644
--- a/windows-installer.cfg
+++ b/windows-installer.cfg
@@ -1,6 +1,6 @@
 [Application]
 name=IRIDA Sequence Uploader
-version=0.3.1
+version=0.3.2
 entry_point=upload_run:main
 icon=gui/images/icon.ico
 # We need to set this to get a console:


Test patch:
diff --git a/tests/config/test_config.py b/tests/config/test_config.py
index 65065f1..a6c46f4 100644
--- a/tests/config/test_config.py
+++ b/tests/config/test_config.py
@@ -53,8 +53,9 @@ class TestConfig(unittest.TestCase):
 
         # Set the config file to False so that the function will check if a default file is set
         config.set_config_file(False)
-        # When it checks for a default path, return False so it will attempt to create a new file
-        mock_path_exists.side_effect = [False]
+        # When it checks for a default path and override path,
+        # return False for bothso it will attempt to create a new file
+        mock_path_exists.side_effect = [False, False]
         # try setting up config to trigger creating a new file
         config.setup()
         # make sure the attempt to create a file happens
@@ -69,9 +70,9 @@ class TestConfig(unittest.TestCase):
     def test_dont_create_new_file_if_exists(self, mock_path_exists, mock_create_new_config_file,
                                             mock_load_config_from_file, mock_init_config_parser):
 
-        # Set the config file to False so that the funtion will check if a default file is set
+        # Set the config file to False so that the function will check if a default file is set
         config.set_config_file(False)
-        # When it checks for a default path, return False so it will attempt to create a new file
+        # When it checks for a default path, return True so it will attempt to use that file
         mock_path_exists.side_effect = [True]
         # If a new file is created, no exit will happen
         config.setup()
@@ -82,6 +83,25 @@ class TestConfig(unittest.TestCase):
         # make sure it tries to load from file
         mock_load_config_from_file.assert_called_with()
 
+    @patch("config.config._init_config_parser")
+    @patch("config.config._load_config_from_file")
+    @patch("config.config._create_new_config_file")
+    @patch("os.path.exists")
+    def test_dont_create_new_file_if_override_file_exists(self, mock_path_exists, mock_create_new_config_file,
+                                                          mock_load_config_from_file, mock_init_config_parser):
+        # Set the config file to False so that the function will check if a default file is set
+        config.set_config_file(False)
+        # When it checks for config files, return True on check for override so it wont attempt to create a new file
+        mock_path_exists.side_effect = [False, True]
+        # If a new file is created, no exit will happen
+        config.setup()
+        # First init happens
+        mock_init_config_parser.assert_called_with()
+        # make sure no attempt to create a file happens
+        mock_create_new_config_file.assert_not_called()
+        # make sure it tries to load from file
+        mock_load_config_from_file.assert_called_with()
+
     def test_read_config_option(self):
         """
         Test writing to config file, make sure writen values are written correctly