changeset 65:d20e6d543ee8

Fixed displayed PEP 8 warnings.
author John Schneiderman
date Fri, 19 Feb 2016 18:45:37 +0100
parents 4f295ab3a0b7
children 28249d6ea0ef
files HgWebManager.kdev4 INSTALL MANIFEST.in README data/ignores.xml doc/CREDITS doc/ChangeLog doc/TODO setup.cfg setup.py src/__init__.py src/_app_info.py src/config.py src/enum.py src/hwm.py src/ignorepo.py src/manager.py src/manrepo.py src/manrepolock.py
diffstat 19 files changed, 1413 insertions(+), 1274 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HgWebManager.kdev4	Fri Feb 19 18:45:37 2016 +0100
@@ -0,0 +1,3 @@
+[Project]
+Manager=KDevGenericManager
+Name=HgWebManager
--- a/INSTALL	Tue Apr 07 20:03:21 2015 +0200
+++ b/INSTALL	Fri Feb 19 18:45:37 2016 +0100
@@ -1,7 +1,7 @@
 ********************************************************************************
 ***  This file is part of HgWeb Manager.                                     ***
 ***                                                                          ***
-***  Copyright (C) 2014 - 2015                                               ***
+***  Copyright (C) 2014 - 2016                                               ***
 ***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
 ***                                                                          ***
 ***  This program is free software: you can redistribute it and/or modify it ***
--- a/MANIFEST.in	Tue Apr 07 20:03:21 2015 +0200
+++ b/MANIFEST.in	Fri Feb 19 18:45:37 2016 +0100
@@ -1,7 +1,7 @@
 #*******************************************************************************
 #**  This file is part of HgWeb Manager.                                     ***
 #**                                                                          ***
-#**  Copyright (C) 2014 - 2015                                               ***
+#**  Copyright (C) 2014 - 2016                                               ***
 #**  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
 #**                                                                          ***
 #**  This program is free software: you can redistribute it and/or modify it ***
--- a/README	Tue Apr 07 20:03:21 2015 +0200
+++ b/README	Fri Feb 19 18:45:37 2016 +0100
@@ -1,7 +1,7 @@
 ********************************************************************************
 ***  This file is part of HgWeb Manager.                                     ***
 ***                                                                          ***
-***  Copyright (C) 2014 - 2015                                               ***
+***  Copyright (C) 2014 - 2016                                               ***
 ***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
 ***                                                                          ***
 ***  This program is free software: you can redistribute it and/or modify it ***
@@ -27,7 +27,7 @@
 Development website: http://www.codegnu.org
 
                               BUILD ENVIRONMENT
-HgWebManager is developed on Mageia 4 using just the standard development
+HgWebManager is developed on Mageia 5 using just the standard development
 libraries, mercurial, and python. In addition, testing on Microsoft Windows
 Server 2008.
 
--- a/data/ignores.xml	Tue Apr 07 20:03:21 2015 +0200
+++ b/data/ignores.xml	Fri Feb 19 18:45:37 2016 +0100
@@ -2,7 +2,7 @@
 <!--****************************************************************************
 ***  This file is part of HgWeb Manager.                                     ***
 ***                                                                          ***
-***  Copyright (C) 2014 - 2015                                               ***
+***  Copyright (C) 2014 - 2016                                               ***
 ***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
 ***                                                                          ***
 ***  This program is free software: you can redistribute it and/or modify it ***
--- a/doc/CREDITS	Tue Apr 07 20:03:21 2015 +0200
+++ b/doc/CREDITS	Fri Feb 19 18:45:37 2016 +0100
@@ -1,7 +1,7 @@
 ********************************************************************************
 ***  This file is part of HgWeb Manager.                                     ***
 ***                                                                          ***
-***  Copyright (C) 2014 - 2015                                               ***
+***  Copyright (C) 2014 - 2016                                               ***
 ***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
 ***                                                                          ***
 ***  This program is free software: you can redistribute it and/or modify it ***
--- a/doc/ChangeLog	Tue Apr 07 20:03:21 2015 +0200
+++ b/doc/ChangeLog	Fri Feb 19 18:45:37 2016 +0100
@@ -1,7 +1,7 @@
 ********************************************************************************
 ***  This file is part of HgWeb Manager.                                     ***
 ***                                                                          ***
-***  Copyright (C) 2014 - 2015                                               ***
+***  Copyright (C) 2014 - 2016                                               ***
 ***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
 ***                                                                          ***
 ***  This program is free software: you can redistribute it and/or modify it ***
@@ -17,8 +17,9 @@
 ***  You should have received a copy of the GNU Affero General Public License***
 ***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
 ********************************************************************************
-2015-XX-XX John Schneiderman <Licensing _AT_ CodeGNU _DOT_ com> 0.5.0
+2016-XX-XX John Schneiderman <Licensing _AT_ CodeGNU _DOT_ com> 0.5.0
 - Split configuration file into logical sections.
+- Brought into PEP 8 compliance.
 2015-03-28 John Schneiderman <Licensing _AT_ CodeGNU _DOT_ com> 0.4.0
 - Ability to add a plug-in to a managed repository.
 - Ability to remove a plug-in from a managed repository.
--- a/doc/TODO	Tue Apr 07 20:03:21 2015 +0200
+++ b/doc/TODO	Fri Feb 19 18:45:37 2016 +0100
@@ -1,7 +1,7 @@
 ********************************************************************************
 ***  This file is part of HgWeb Manager.                                     ***
 ***                                                                          ***
-***  Copyright (C) 2014 - 2015                                               ***
+***  Copyright (C) 2014 - 2016                                               ***
 ***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
 ***                                                                          ***
 ***  This program is free software: you can redistribute it and/or modify it ***
@@ -29,9 +29,6 @@
 ***                                                                          ***
 - Installation tutorial.
 - User tutorials.
-- Manager functions should take both an output and error device instead of defaulting to std.
-- Manager should handle the HgWeb configuration file settings.
-	* Create a separate manager for the HgWeb configuration file.
 - Manager should provide a REST API for repository management.
 - Manager should have an API key per user permission values.
-- Prevent a push that would create multiple heads
+- Add support for integrating with Mercurial-Server, http://www.lshift.net/work/open-source/mercurial-server/
--- a/setup.cfg	Tue Apr 07 20:03:21 2015 +0200
+++ b/setup.cfg	Fri Feb 19 18:45:37 2016 +0100
@@ -2,7 +2,7 @@
 #*******************************************************************************
 #**  This file is part of HgWeb Manager.                                     ***
 #**                                                                          ***
-#**  Copyright (C) 2014 - 2015                                               ***
+#**  Copyright (C) 2014 - 2016                                               ***
 #**  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
 #**                                                                          ***
 #**  This program is free software: you can redistribute it and/or modify it ***
--- a/setup.py	Tue Apr 07 20:03:21 2015 +0200
+++ b/setup.py	Fri Feb 19 18:45:37 2016 +0100
@@ -1,24 +1,25 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
-'''*****************************************************************************
-***  This file is part of HgWeb Manager.                                     ***
-***                                                                          ***
-***  Copyright (C) 2014 - 2015                                               ***
-***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Affero General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Affero General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Affero General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*****************************************************************************'''
+'''****************************************************************************
+***  This file is part of HgWeb Manager.                                    ***
+***                                                                         ***
+***  Copyright (C) 2014 - 2016                                              ***
+***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                   ***
+***                                                                         ***
+***  This program is free software: you can redistribute it and/or modify   ***
+***  it under the terms of the GNU Affero General Public License as         ***
+***  published by the Free Software Foundation, either version 3 of the     ***
+***  License, or (at your option) any later version.                        ***
+***                                                                         ***
+***  This program is distributed in the hope that it will be useful, but    ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of             ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                   ***
+***  See the GNU Affero General Public License for more details.            ***
+***                                                                         ***
+***  You should have received a copy of the GNU Affero General Public       ***
+***  License along with this program. If not,                               ***
+***  see <http://www.gnu.org/licenses/>.                                    ***
+****************************************************************************'''
 
 
 from distutils.core import setup
@@ -28,58 +29,59 @@
 from _app_info import VERSION, DESCRIPTION, LONG_DESCRIPTION, SHORT_NAME
 
 required = \
-	[
-		'mercurial',
-		'mercurial.hg',
-		'mercurial.ui',
-		'mercurial.error',
-		'mercurial.hgweb'
-	]
+    [
+        'mercurial',
+        'mercurial.hg',
+        'mercurial.ui',
+        'mercurial.error',
+        'mercurial.hgweb'
+    ]
 
 # Basic package setup information
 setup(
-	name=SHORT_NAME,
-	version=VERSION,
-	description=DESCRIPTION,
-	long_description=LONG_DESCRIPTION,
-	author='CodeGNU Solutions',
-	author_email='Licensing@CodeGNU.com',
-	url='http://www.codegnu.com',
-	download_url="http://www.codegnu.com/files/hwm-{0}.tar.gz".format(VERSION),
-	license='AGPLv3+',
-	packages=['HgWebManager'],
-	package_dir={'HgWebManager': 'src'},
-	provides=['HgWebManager'],
-	requires=required,
-	platforms=[
-		'GNU/Linux',
-		'POSIX',
-		'Mac OS',
-		'Windows'
-	],
-	classifiers=[
-		'Development Status :: 3 - Alpha',
-		'Environment :: Console',
-		'Environment :: Web Environment',
-		'Intended Audience :: Developers',
-		'Intended Audience :: System Administrators',
-		'Intended Audience :: Information Technology',
-		'License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)',
-		'Natural Language :: English',
-		'Operating System :: MacOS',
-		'Operating System :: Microsoft :: Windows',
-		'Operating System :: POSIX :: Linux',
-		'Programming Language :: Python :: 2.7',
-		'Topic :: Internet :: WWW/HTTP :: Site Management',
-		'Topic :: Software Development :: Version Control',
-		'Topic :: System :: Systems Administration'
-	],
-	data_files=[
-		(
-			"share/" + SHORT_NAME,
-			[
-				'ignores.xml'
-			]
-		),
-	],
+    name=SHORT_NAME,
+    version=VERSION,
+    description=DESCRIPTION,
+    long_description=LONG_DESCRIPTION,
+    author='CodeGNU Solutions',
+    author_email='Licensing@CodeGNU.com',
+    url='http://www.codegnu.com',
+    download_url="http://www.codegnu.com/files/hwm-{0}.tar.gz".format(VERSION),
+    license='AGPLv3+',
+    packages=['HgWebManager'],
+    package_dir={'HgWebManager': 'src'},
+    provides=['HgWebManager'],
+    requires=required,
+    platforms=[
+        'GNU/Linux',
+        'POSIX',
+        'Mac OS',
+        'Windows'
+    ],
+    classifiers=[
+        'Development Status :: 3 - Alpha',
+        'Environment :: Console',
+        'Environment :: Web Environment',
+        'Intended Audience :: Developers',
+        'Intended Audience :: System Administrators',
+        'Intended Audience :: Information Technology',
+        'License :: OSI Approved :: GNU Affero General Public License '
+        'v3 or later (AGPLv3+)',
+        'Natural Language :: English',
+        'Operating System :: MacOS',
+        'Operating System :: Microsoft :: Windows',
+        'Operating System :: POSIX :: Linux',
+        'Programming Language :: Python :: 2.7',
+        'Topic :: Internet :: WWW/HTTP :: Site Management',
+        'Topic :: Software Development :: Version Control',
+        'Topic :: System :: Systems Administration'
+    ],
+    data_files=[
+        (
+            "share/" + SHORT_NAME,
+            [
+                'ignores.xml'
+            ]
+        ),
+    ],
 )
--- a/src/__init__.py	Tue Apr 07 20:03:21 2015 +0200
+++ b/src/__init__.py	Fri Feb 19 18:45:37 2016 +0100
@@ -1,20 +1,21 @@
 # -*- coding: utf-8 -*-
-'''*****************************************************************************
-***  This file is part of HgWeb Manager.                                     ***
-***                                                                          ***
-***  Copyright (C) 2014 - 2015                                               ***
-***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Affero General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Affero General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Affero General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*****************************************************************************'''
+'''****************************************************************************
+***  This file is part of HgWeb Manager.                                    ***
+***                                                                         ***
+***  Copyright (C) 2014 - 2016                                              ***
+***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                   ***
+***                                                                         ***
+***  This program is free software: you can redistribute it and/or modify   ***
+***  it under the terms of the GNU Affero General Public License as         ***
+***  published by the Free Software Foundation, either version 3 of the     ***
+***  License, or (at your option) any later version.                        ***
+***                                                                         ***
+***  This program is distributed in the hope that it will be useful, but    ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of             ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                   ***
+***  See the GNU Affero General Public License for more details.            ***
+***                                                                         ***
+***  You should have received a copy of the GNU Affero General Public       ***
+***  License along with this program. If not,                               ***
+***  see <http://www.gnu.org/licenses/>.                                    ***
+****************************************************************************'''
--- a/src/_app_info.py	Tue Apr 07 20:03:21 2015 +0200
+++ b/src/_app_info.py	Fri Feb 19 18:45:37 2016 +0100
@@ -1,23 +1,24 @@
 # -*- coding: utf-8 -*-
-'''*****************************************************************************
-***  This file is part of HgWeb Manager.                                     ***
-***                                                                          ***
-***  Copyright (C) 2014 - 2015                                               ***
-***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Affero General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Affero General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Affero General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*****************************************************************************'''
+'''****************************************************************************
+***  This file is part of HgWeb Manager.                                    ***
+***                                                                         ***
+***  Copyright (C) 2014 - 2016                                              ***
+***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                   ***
+***                                                                         ***
+***  This program is free software: you can redistribute it and/or modify   ***
+***  it under the terms of the GNU Affero General Public License as         ***
+***  published by the Free Software Foundation, either version 3 of the     ***
+***  License, or (at your option) any later version.                        ***
+***                                                                         ***
+***  This program is distributed in the hope that it will be useful, but    ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of             ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                   ***
+***  See the GNU Affero General Public License for more details.            ***
+***                                                                         ***
+***  You should have received a copy of the GNU Affero General Public       ***
+***  License along with this program. If not,                               ***
+***  see <http://www.gnu.org/licenses/>.                                    ***
+****************************************************************************'''
 
 
 # The shortened name of the application
@@ -27,13 +28,14 @@
 LONG_NAME = 'HgWeb Manager'
 
 # The current version of the application
-VERSION = '0.4.0'
+VERSION = '0.5.0'
 
 # The current copyright years.
-YEARS = '2014 - 2015'
+YEARS = '2014 - 2016'
 
 # A short description of the application
 DESCRIPTION = 'Manages HgWeb Repositories'
 
 # A long description of the application
-LONG_DESCRIPTION = 'An application to simplify the management of repositories shared through the Mercurial web publishing method.'
+LONG_DESCRIPTION = 'An application to simplify the management of ' \
+    'repositories shared through the Mercurial web publishing method.'
--- a/src/config.py	Tue Apr 07 20:03:21 2015 +0200
+++ b/src/config.py	Fri Feb 19 18:45:37 2016 +0100
@@ -1,116 +1,121 @@
 # -*- coding: utf-8 -*-
-'''*****************************************************************************
-***  This file is part of HgWeb Manager.                                     ***
-***                                                                          ***
-***  Copyright (C) 2014 - 2015                                               ***
-***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Affero General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Affero General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Affero General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*****************************************************************************'''
+'''****************************************************************************
+***  This file is part of HgWeb Manager.                                    ***
+***                                                                         ***
+***  Copyright (C) 2014 - 2016                                              ***
+***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                   ***
+***                                                                         ***
+***  This program is free software: you can redistribute it and/or modify   ***
+***  it under the terms of the GNU Affero General Public License as         ***
+***  published by the Free Software Foundation, either version 3 of the     ***
+***  License, or (at your option) any later version.                        ***
+***                                                                         ***
+***  This program is distributed in the hope that it will be useful, but    ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of             ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                   ***
+***  See the GNU Affero General Public License for more details.            ***
+***                                                                         ***
+***  You should have received a copy of the GNU Affero General Public       ***
+***  License along with this program. If not,                               ***
+***  see <http://www.gnu.org/licenses/>.                                    ***
+****************************************************************************'''
 
 
 class Manager(object):
-	""" Manages the configurations for HgWebManager """
+    """ Manages the configurations for HgWebManager """
 
-	# The configuration file parser.
-	__parser = None
+    # The configuration file parser.
+    __parser = None
 
-	# The absolute directory path and file name of the hg command.
-	__hgCommand = None
+    # The absolute directory path and file name of the hg command.
+    __hgCommand = None
 
-	@property
-	def HgCommand(self):
-		""" Gets the command for executing mercurial. """
-		return self.__hgCommand
+    @property
+    def HgCommand(self):
+        """ Gets the command for executing mercurial. """
+        return self.__hgCommand
+
+    # The absolute directory path to the managed HgWeb repositories.
+    __repositoryPath = None
 
-	# The absolute directory path to the managed HgWeb repositories.
-	__repositoryPath = None
+    @property
+    def RepositoryPath(self):
+        """ Gets the directory path to the managed repositories. """
+        return self.__repositoryPath
 
-	@property
-	def RepositoryPath(self):
-		""" Gets the directory path to the managed repositories. """
-		return self.__repositoryPath
+    # The absolute directory path to the HgWeb web-server site.
+    __hgWebPath = None
 
-	# The absolute directory path to the HgWeb web-server site.
-	__hgWebPath = None
+    @property
+    def HgWebPath(self):
+        """ Gets the directory path to the repository web-server site. """
+        return self.__hgWebPath
 
-	@property
-	def HgWebPath(self):
-		""" Gets the directory path to the repository web-server site. """
-		return self.__hgWebPath
-
-	# The directory path for HWM data.
-	__dataPath = None
+    # The directory path for HWM data.
+    __dataPath = None
 
-	@property
-	def DataPath(self):
-		""" Gets the directory path to the HWM data directory. """
-		return self.__dataPath
+    @property
+    def DataPath(self):
+        """ Gets the directory path to the HWM data directory. """
+        return self.__dataPath
+
+    # The user-name of the Mercurial web-manager.
+    __hgUser = None
 
-	# The user-name of the Mercurial web-manager.
-	__hgUser = None
+    @property
+    def HgUser(self):
+        """ Gets the user-name of the web-manager. """
+        return self.__hgUser
 
-	@property
-	def HgUser(self):
-		""" Gets the user-name of the web-manager. """
-		return self.__hgUser
+    def __init__(self, path=['/etc/hwm.ini', '~/.hwm/hwm.ini', './hwm.ini']):
+        """ Loads the settings values stored in the configuration file.
 
-	def __init__(self, path=['/etc/hwm.ini', '~/.hwm/hwm.ini', './hwm.ini']):
-		""" Loads the settings values stored in the configuration file.
-
-		@param[in] path	The path and file name of the configuration file.
+        @param[in] path    The path and file name of the configuration file.
 
-		@throws ValueError		When the configuration file cannot be found.
-		@throw RuntimeError		When the configuration file is missing required
-								entries.
-		"""
-		from ConfigParser import SafeConfigParser
+        @throws ValueError        When the configuration file cannot be found.
+        @throw RuntimeError       When the configuration file is missing
+                                  required entries.
+        """
+        from ConfigParser import SafeConfigParser
 
-		self.__parser = SafeConfigParser()
-		if not self.__parser.read(path):
-			raise ValueError("Failed to find configuration file.")
+        self.__parser = SafeConfigParser()
+        if not self.__parser.read(path):
+            raise ValueError("Failed to find configuration file.")
 
-		if self.__parser.has_section('Mercurial'):
-			if self.__parser.has_option('Mercurial', 'Command'):
-				self.__hgCommand = self.__parser.get('Mercurial', 'Command')
-			else:
-				self.__hgCommand = '/usr/bin/hg'
-		else:
-			self.__hgCommand = '/usr/bin/hg'
+        if self.__parser.has_section('Mercurial'):
+            if self.__parser.has_option('Mercurial', 'Command'):
+                self.__hgCommand = self.__parser.get('Mercurial', 'Command')
+            else:
+                self.__hgCommand = '/usr/bin/hg'
+        else:
+            self.__hgCommand = '/usr/bin/hg'
 
-		if self.__parser.has_section('HgWeb'):
-			if self.__parser.has_option('HgWeb', 'Base'):
-				self.__repositoryPath = self.__parser.get('HgWeb', 'Base')
-			else:
-				raise RuntimeError('Failed to locate the HgWeb-Base entry')
+        if self.__parser.has_section('HgWeb'):
+            if self.__parser.has_option('HgWeb', 'Base'):
+                self.__repositoryPath = self.__parser.get('HgWeb', 'Base')
+            else:
+                raise RuntimeError('Failed to locate the HgWeb-Base entry')
 
-			if self.__parser.has_option('HgWeb', 'Server'):
-				self.__hgWebPath = self.__parser.get('HgWeb', 'Server')
-			else:
-				raise RuntimeError('Failed to locate the HgWeb-Server entry')
-		else:
-			raise RuntimeError('Failed to locate the HgWeb configuration section')
+            if self.__parser.has_option('HgWeb', 'Server'):
+                self.__hgWebPath = self.__parser.get('HgWeb', 'Server')
+            else:
+                raise RuntimeError('Failed to locate the HgWeb-Server entry')
+        else:
+            raise RuntimeError(
+                'Failed to locate the HgWeb configuration section'
+            )
 
-		if self.__parser.has_section('HWM'):
-			if self.__parser.has_option('HWM', 'Data'):
-				self.__dataPath = self.__parser.get('HWM', 'Data')
-			else:
-				self.__dataPath = '/usr/share/hwm'
+        if self.__parser.has_section('HWM'):
+            if self.__parser.has_option('HWM', 'Data'):
+                self.__dataPath = self.__parser.get('HWM', 'Data')
+            else:
+                self.__dataPath = '/usr/share/hwm'
 
-			if self.__parser.has_option('HWM', 'Manager'):
-				self.__hgUser = self.__parser.get('HWM', 'Manager')
-			else:
-				raise RuntimeError('Failed to locate the HWM-Manager entry')
-		else:
-			raise RuntimeError('Failed to locate the HWM configuration section')
+            if self.__parser.has_option('HWM', 'Manager'):
+                self.__hgUser = self.__parser.get('HWM', 'Manager')
+            else:
+                raise RuntimeError('Failed to locate the HWM-Manager entry')
+        else:
+            raise RuntimeError(
+                'Failed to locate the HWM configuration section'
+            )
--- a/src/enum.py	Tue Apr 07 20:03:21 2015 +0200
+++ b/src/enum.py	Fri Feb 19 18:45:37 2016 +0100
@@ -1,34 +1,35 @@
 # -*- coding: utf-8 -*-
-'''*****************************************************************************
-***  This file is part of HgWeb Manager.                                     ***
-***                                                                          ***
-***  Copyright (C) 2014 - 2015                                               ***
-***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Affero General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Affero General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Affero General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*****************************************************************************'''
+'''****************************************************************************
+***  This file is part of HgWeb Manager.                                    ***
+***                                                                         ***
+***  Copyright (C) 2014 - 2016                                              ***
+***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                   ***
+***                                                                         ***
+***  This program is free software: you can redistribute it and/or modify   ***
+***  it under the terms of the GNU Affero General Public License as         ***
+***  published by the Free Software Foundation, either version 3 of the     ***
+***  License, or (at your option) any later version.                        ***
+***                                                                         ***
+***  This program is distributed in the hope that it will be useful, but    ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of             ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                   ***
+***  See the GNU Affero General Public License for more details.            ***
+***                                                                         ***
+***  You should have received a copy of the GNU Affero General Public       ***
+***  License along with this program. If not,                               ***
+***  see <http://www.gnu.org/licenses/>.                                    ***
+****************************************************************************'''
 
 
 def create(*sequential, **named):
-	""" Creates a type which mimics the behaviour of an enumeration.
+    """ Creates a type which mimics the behaviour of an enumeration.
 
-	@param[in] sequential
-	@param[in] named
+    @param[in] sequential
+    @param[in] named
 
-	@return An object which contains the supplied enumerated values.
-	"""
-	enums = dict(zip(sequential, range(len(sequential))), **named)
-	reverse = dict((value, key) for key, value in enums.iteritems())
-	enums['reverse_mapping'] = reverse
-	return type('Enum', (), enums)
+    @return An object which contains the supplied enumerated values.
+    """
+    enums = dict(zip(sequential, range(len(sequential))), **named)
+    reverse = dict((value, key) for key, value in enums.iteritems())
+    enums['reverse_mapping'] = reverse
+    return type('Enum', (), enums)
--- a/src/hwm.py	Tue Apr 07 20:03:21 2015 +0200
+++ b/src/hwm.py	Fri Feb 19 18:45:37 2016 +0100
@@ -1,160 +1,201 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
-'''*****************************************************************************
-***  This file is part of HgWeb Manager.                                     ***
-***                                                                          ***
-***  Copyright (C) 2014 - 2015                                               ***
-***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Affero General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Affero General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Affero General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*****************************************************************************'''
+'''****************************************************************************
+***  This file is part of HgWeb Manager.                                    ***
+***                                                                         ***
+***  Copyright (C) 2014 - 2016                                              ***
+***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                   ***
+***                                                                         ***
+***  This program is free software: you can redistribute it and/or modify   ***
+***  it under the terms of the GNU Affero General Public License as         ***
+***  published by the Free Software Foundation, either version 3 of the     ***
+***  License, or (at your option) any later version.                        ***
+***                                                                         ***
+***  This program is distributed in the hope that it will be useful, but    ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of             ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                   ***
+***  See the GNU Affero General Public License for more details.            ***
+***                                                                         ***
+***  You should have received a copy of the GNU Affero General Public       ***
+***  License along with this program. If not,                               ***
+***  see <http://www.gnu.org/licenses/>.                                    ***
+****************************************************************************'''
 
 
 def is_hgWeb_user(expectedHgUser):
-	""" Determines if the current running user is the expected HgWeb user.
+    """ Determines if the current running user is the expected HgWeb user.
 
-	@param[in] str expectedHgUser	The expected user-name for the Mercurial
-									web-manager.
+    @param[in] str expectedHgUser    The expected user-name for the Mercurial
+                                    web-manager.
 
-	@return Gives true when the user is the expected HgWeb user, false
-	else-wise.
-	"""
-	import getpass
+    @return Gives true when the user is the expected HgWeb user, false
+    else-wise.
+    """
+    import getpass
 
-	# FIXME: This isn't a secure check as it is based upon the environmental variable.
-	if expectedHgUser == getpass.getuser():
-		return True
-	else:
-		return False
+    # FIXME: This isn't a secure check as it is based upon the
+    # environmental variable.
+    if expectedHgUser == getpass.getuser():
+        return True
+    else:
+        return False
 
 
 def __extract_values(args):
-	""" Pulls the creation arguments out of the command-line. The returned
-	object is filled with the repository details when it exists and any of the
-	detail values supplied on the command-line will replace the one found in
-	the repository details.
+    """ Pulls the creation arguments out of the command-line. The returned
+    object is filled with the repository details when it exists and any of the
+    detail values supplied on the command-line will replace the one found in
+    the repository details.
 
-	@param[in] args	The command-line argument processor containing the
-					creation argument values.
+    @param[in] args    The command-line argument processor containing the
+                    creation argument values.
 
-	@return A managed repository object.
-	"""
-	import manrepo
+    @return A managed repository object.
+    """
+    import manrepo
 
-	managed = None
-	if args.rename:
-		original = manrepo.Repository(args.storage)
-		managed = manrepo.Repository(args.rename)
-		managed.DisplayName = original.DisplayName
-		managed.Description = original.Description
-		managed.Contact = original.Contact
-	elif args.storage:
-		managed = manrepo.Repository(args.storage)
-	else:
-		raise ValueError("Missing repository storage name.")
+    managed = None
+    if args.rename:
+        original = manrepo.Repository(args.storage)
+        managed = manrepo.Repository(args.rename)
+        managed.DisplayName = original.DisplayName
+        managed.Description = original.Description
+        managed.Contact = original.Contact
+    elif args.storage:
+        managed = manrepo.Repository(args.storage)
+    else:
+        raise ValueError("Missing repository storage name.")
 
-	if args.name:
-		managed.DisplayName = args.name
+    if args.name:
+        managed.DisplayName = args.name
 
-	if args.description:
-		managed.Description = args.description
+    if args.description:
+        managed.Description = args.description
 
-	if args.contact:
-		managed.Contact = args.contact
+    if args.contact:
+        managed.Contact = args.contact
 
-	return managed
+    return managed
 
 if __name__ == '__main__':
-	import _app_info
-	import sys
+    import _app_info
+    import sys
 
-	try:
-		# Display license
-		print "%s %s Copyright (C) %s CodeGNU Solutions" % \
-			(_app_info.LONG_NAME, _app_info.VERSION, _app_info.YEARS)
-		print "%s comes with ABSOLUTELY NO WARRANTY;" % (_app_info.SHORT_NAME)
-		print 'This is free software, and you are welcome to redistribute it'
-		print 'under certain conditions; see the LICENSE file for details,'
-		print 'or the Free Software Foundation\'s AGPL.\n'
+    try:
+        # Display license
+        print "%s %s Copyright (C) %s CodeGNU Solutions" % \
+            (_app_info.LONG_NAME, _app_info.VERSION, _app_info.YEARS)
+        print "%s comes with ABSOLUTELY NO WARRANTY;" % (_app_info.SHORT_NAME)
+        print 'This is free software, and you are welcome to redistribute it'
+        print 'under certain conditions; see the LICENSE file for details,'
+        print 'or the Free Software Foundation\'s AGPL.\n'
 
-		from manager import settings
-		import argparse
-		import manager
+        from manager import settings
+        import argparse
+        import manager
 
-		if not is_hgWeb_user(settings.HgUser):
-			print >>sys.stderr, 'Must execute as the Mercurial Web manager.'
-			exit(1)
+        if not is_hgWeb_user(settings.HgUser):
+            print >>sys.stderr, 'Must execute as the Mercurial Web manager.'
+            exit(1)
 
-		parser = argparse.ArgumentParser(description=_app_info.DESCRIPTION)
-		parser.add_argument('-l', '--list', action='store_true', help='Outputs a list of all the managed repositories.')
-
-		plgInGrp = parser.add_argument_group('Manage Plug-Ins', 'Options that operate upon a managed repository\'s plug-ins.')
-		plgInGrp.add_argument('-p', '--plugin', action='store', nargs=1, type=str, default=None, help='The name of a plug-in for a repository.')
-		plgInGrp.add_argument('-e', '--enable', action='store_true', help='Enable a plug-in in a repository.')
-		plgInGrp.add_argument('-f', '--script-path', action='store', nargs='?', type=str, default=None, help='The path to the plug-in script.')
-		plgInGrp.add_argument('-x', '--disable', action='store_true', help='Disable a plug-in in a repository.')
-		plgInGrp.add_argument('-s', '--setting', action='store', nargs=2, type=str, default=None, help='Sets a setting name/value pair for a plug-in.')
+        parser = argparse.ArgumentParser(description=_app_info.DESCRIPTION)
+        parser.add_argument('-l', '--list', action='store_true',
+                            help='Outputs a list of all the managed '
+                            'repositories.')
 
-		manGrp = parser.add_argument_group('Manage Repositories', 'Options that operate upon managed repositories.')
-		manGrp.add_argument('storage', action='store', nargs='?', help='The storage-name of the repository to perform an action upon.')
-		manGrp.add_argument('-a', '--action', action='store', nargs=1, type=str, choices=['c', 'create', 'm', 'modify', 'd', 'delete', 'r', 'register'], help='Performs an action upon a managed repository.')
-		manGrp.add_argument('-i', '--ignore', action='store', nargs='+', default=None, help='The groups to place in an ignore file.')
-		manGrp.add_argument('-k', '--skip-common', action='store_true', help='The common ignore group is not added by default.')
-		manGrp.add_argument('-n', '--name', action='store', nargs='?', default=None, help='The display name of the repository.')
-		manGrp.add_argument('-d', '--description', action='store', nargs='?', default=None, help='The description of the repository.')
-		manGrp.add_argument('-c', '--contact', action='store', nargs='?', default=None, help='The contact point of a repository.')
-		manGrp.add_argument('-r', '--rename', action='store', nargs='?', default=None, help='The new storage-name for a repository.')
+        plgInGrp = parser.add_argument_group('Manage Plug-Ins',
+                                             'Options that operate upon a '
+                                             'managed repository\'s plug-ins.')
+        plgInGrp.add_argument('-p', '--plugin', action='store', nargs=1,
+                              type=str, default=None,
+                              help='The name of a plug-in for a repository.')
+        plgInGrp.add_argument('-e', '--enable', action='store_true',
+                              help='Enable a plug-in in a repository.')
+        plgInGrp.add_argument('-f', '--script-path', action='store', nargs='?',
+                              type=str, default=None,
+                              help='The path to the plug-in script.')
+        plgInGrp.add_argument('-x', '--disable', action='store_true',
+                              help='Disable a plug-in in a repository.')
+        plgInGrp.add_argument('-s', '--setting', action='store', nargs=2,
+                              type=str, default=None,
+                              help='Sets a setting name/value pair '
+                              'for a plug-in.')
 
-		# Examine the supplied arguments and perform requested actions.
-		args = parser.parse_args()
-		repo = __extract_values(args)
+        manGrp = parser.add_argument_group('Manage Repositories',
+                                           'Options that operate upon '
+                                           'managed repositories.')
+        manGrp.add_argument('storage', action='store', nargs='?',
+                            help='The storage-name of the repository to '
+                            'perform an action upon.')
+        manGrp.add_argument('-a', '--action', action='store', nargs=1,
+                            type=str, choices=['c', 'create', 'm', 'modify',
+                                               'd', 'delete', 'r', 'register'],
+                            help='Performs an action upon a managed '
+                            'repository.')
+        manGrp.add_argument('-i', '--ignore', action='store', nargs='+',
+                            default=None,
+                            help='The groups to place in an ignore file.')
+        manGrp.add_argument('-k', '--skip-common', action='store_true',
+                            help='The common ignore group is not added '
+                            'by default.')
+        manGrp.add_argument('-n', '--name', action='store', nargs='?',
+                            default=None,
+                            help='The display name of the repository.')
+        manGrp.add_argument('-d', '--description', action='store', nargs='?',
+                            default=None,
+                            help='The description of the repository.')
+        manGrp.add_argument('-c', '--contact', action='store', nargs='?',
+                            default=None,
+                            help='The contact point of a repository.')
+        manGrp.add_argument('-r', '--rename', action='store', nargs='?',
+                            default=None,
+                            help='The new storage-name for a repository.')
+
+        # Examine the supplied arguments and perform requested actions.
+        args = parser.parse_args()
+        repo = __extract_values(args)
 
-		if args.list:
-			manager.list()
-		elif args.plugin is not None:
-			if args.enable:
-				manager.plugInEnable(repo, args.plugin[0], args.script_path)
-			elif args.disable:
-				manager.plugInDisable(repo, args.plugin[0])
-			elif args.setting is not None:
-				if len(args.setting[1]) > 0:
-					manager.setPlugInSetting(repo, args.plugin[0], args.setting[0], args.setting[1])
-				else:
-					manager.setPlugInSetting(repo, args.plugin[0], args.setting[0], None)
-			else:
-				print >>sys.stderr, "Failure determine requested plug-in '%s' option." % args.plugin[0]
-				exit(1)
-		elif args.action is None:
-			print >>sys.stderr, "No repository operation argument supplied."
-			exit(1)
-		elif ('create' == args.action[0]) or ('c' == args.action[0]):
-			manager.create(repo, args.ignore, args.skip_common)
-		elif ('modify' == args.action[0]) or ('m' == args.action[0]):
-			manager.modify(repo, args.storage, args.ignore, args.skip_common)
-		elif ('delete' == args.action[0]) or ('d' == args.action[0]):
-			manager.delete(repo)
-		elif ('register' == args.action[0]) or ('r' == args.action[0]):
-			manager.register(repo)
-		else:
-			print >>sys.stderr, "Unknown repository action supplied '%s'." % args.action[0]
-			exit(1)
-		exit(0)
-	except (ValueError, RuntimeError) as error:
-		print >>sys.stderr, "Execution Failed: %s" % error
-		exit(2)
-	except Exception as error:
-		import traceback
+        if args.list:
+            manager.list()
+        elif args.plugin is not None:
+            if args.enable:
+                manager.plugInEnable(repo, args.plugin[0], args.script_path)
+            elif args.disable:
+                manager.plugInDisable(repo, args.plugin[0])
+            elif args.setting is not None:
+                if len(args.setting[1]) > 0:
+                    manager.setPlugInSetting(repo, args.plugin[0],
+                                             args.setting[0], args.setting[1])
+                else:
+                    manager.setPlugInSetting(repo, args.plugin[0],
+                                             args.setting[0], None)
+            else:
+                print >>sys.stderr, \
+                    "Failure determine requested plug-in '%s' option." % \
+                    args.plugin[0]
+                exit(1)
+        elif args.action is None:
+            print >>sys.stderr, "No repository operation argument supplied."
+            exit(1)
+        elif ('create' == args.action[0]) or ('c' == args.action[0]):
+            manager.create(repo, args.ignore, args.skip_common)
+        elif ('modify' == args.action[0]) or ('m' == args.action[0]):
+            manager.modify(repo, args.storage, args.ignore, args.skip_common)
+        elif ('delete' == args.action[0]) or ('d' == args.action[0]):
+            manager.delete(repo)
+        elif ('register' == args.action[0]) or ('r' == args.action[0]):
+            manager.register(repo)
+        else:
+            print >>sys.stderr, \
+                "Unknown repository action supplied '%s'." % args.action[0]
+            exit(1)
+        exit(0)
+    except (ValueError, RuntimeError) as error:
+        print >>sys.stderr, "Execution Failed: %s" % error
+        exit(2)
+    except Exception as error:
+        import traceback
 
-		print >>sys.stderr, "Unexpected error: %s\n" % error, '-' * 60, '\n', traceback.format_exc(), '-' * 60
-		exit(3)
+        print >>sys.stderr, "Unexpected error: %s\n" % error, '-' * 60, '\n',
+        traceback.format_exc(), '-' * 60
+        exit(3)
--- a/src/ignorepo.py	Tue Apr 07 20:03:21 2015 +0200
+++ b/src/ignorepo.py	Fri Feb 19 18:45:37 2016 +0100
@@ -1,23 +1,24 @@
 # -*- coding: utf-8 -*-
-'''*****************************************************************************
-***  This file is part of HgWeb Manager.                                     ***
-***                                                                          ***
-***  Copyright (C) 2014 - 2015                                               ***
-***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Affero General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Affero General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Affero General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*****************************************************************************'''
+'''****************************************************************************
+***  This file is part of HgWeb Manager.                                    ***
+***                                                                         ***
+***  Copyright (C) 2014 - 2016                                              ***
+***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                   ***
+***                                                                         ***
+***  This program is free software: you can redistribute it and/or modify   ***
+***  it under the terms of the GNU Affero General Public License as         ***
+***  published by the Free Software Foundation, either version 3 of the     ***
+***  License, or (at your option) any later version.                        ***
+***                                                                         ***
+***  This program is distributed in the hope that it will be useful, but    ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of             ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                   ***
+***  See the GNU Affero General Public License for more details.            ***
+***                                                                         ***
+***  You should have received a copy of the GNU Affero General Public       ***
+***  License along with this program. If not,                               ***
+***  see <http://www.gnu.org/licenses/>.                                    ***
+****************************************************************************'''
 
 import enum
 
@@ -27,106 +28,105 @@
 
 
 def ignore_syntax_name(mapFilterType):
-	""" Provides the mapping between an enumerated filter type and the
-	Mercurial ignore section header.
+    """ Provides the mapping between an enumerated filter type and the
+    Mercurial ignore section header.
 
-	@param[in] mapFilterType	Is the enumerated value to map.
+    @param[in] mapFilterType    Is the enumerated value to map.
 
-	@throws ValueError	When an invalid filtering type is supplied.
+    @throws ValueError    When an invalid filtering type is supplied.
 
-	@return The string value of the supplied enumerated value.
-	"""
-	if FilterType.Glob == mapFilterType:
-		return 'glob'
-	elif FilterType.RegularExpression == mapFilterType:
-		return 'regexp'
-	else:
-		raise ValueError("Unknown filter type supplied, '%s'." % mapFilterType)
+    @return The string value of the supplied enumerated value.
+    """
+    if FilterType.Glob == mapFilterType:
+        return 'glob'
+    elif FilterType.RegularExpression == mapFilterType:
+        return 'regexp'
+    else:
+        raise ValueError("Unknown filter type supplied, '%s'." % mapFilterType)
 
 
 class Pattern(object):
-	""" Describes the properties of an entry in a Mercurial ignore file. """
+    """ Describes the properties of an entry in a Mercurial ignore file. """
 
-	# A short entry describing the purpose of the ignore entry.
-	__description = None
-	# The type of ignore entry used by Mercurial.
-	__filter = None
-	# The ignore expression to provide for an ignore file.
-	__value = None
+    # A short entry describing the purpose of the ignore entry.
+    __description = None
+    # The type of ignore entry used by Mercurial.
+    __filter = None
+    # The ignore expression to provide for an ignore file.
+    __value = None
 
-	@property
-	def Description(self):
-		""" A short entry describing the purpose of the ignore entry when
-		provided, else gives miscellaneous.
-		"""
-		if self.__description:
-			return self.__description
-		else:
-			return 'Miscellaneous'
+    @property
+    def Description(self):
+        """ A short entry describing the purpose of the ignore entry when
+        provided, else gives miscellaneous.
+        """
+        if self.__description:
+            return self.__description
+        else:
+            return 'Miscellaneous'
 
-	@property
-	def Filter(self):
-		""" The type of ignore entry used by Mercurial. """
-		return self.__filter
+    @property
+    def Filter(self):
+        """ The type of ignore entry used by Mercurial. """
+        return self.__filter
 
-	@property
-	def Value(self):
-		""" The ignore expression to provide for an ignore file. """
-		return self.__value
+    @property
+    def Value(self):
+        """ The ignore expression to provide for an ignore file. """
+        return self.__value
 
-	def __init__(self, desc, fil, val):
-		""" Initialises the object with the values supplied.
+    def __init__(self, desc, fil, val):
+        """ Initialises the object with the values supplied.
 
-		@param[in] desc	The description of the ignore entry.
-		@param[in] fil	The type of ignore filtering.
-		@param[in] val	The ignore expression.
+        @param[in] desc    The description of the ignore entry.
+        @param[in] fil    The type of ignore filtering.
+        @param[in] val    The ignore expression.
 
-		@throws ValueError		When the supplied ignore filter is invalid.
-		"""
-		self.__description = desc.strip()
-		if fil == 'glob':
-			self.__filter = FilterType.Glob
-		elif fil == 'regex':
-			self.__filter = FilterType.RegularExpression
-		else:
-			raise ValueError("Invalid filter type '%s' supplied" % fil)
-		self.__value = val.strip()
+        @throws ValueError        When the supplied ignore filter is invalid.
+        """
+        self.__description = desc.strip()
+        if fil == 'glob':
+            self.__filter = FilterType.Glob
+        elif fil == 'regex':
+            self.__filter = FilterType.RegularExpression
+        else:
+            raise ValueError("Invalid filter type '%s' supplied" % fil)
+        self.__value = val.strip()
 
 
 def extract(ignoreFile):
-	""" Parses an XML file for ignore file patterns. Generates a dictionary
-	object whose key is the name of the group for a collection of ignore
-	patterns. The value in each dictionary is an array of all the ignore
-	pattern objects within that group. Upon any parsing error, no ignore
-	patterns are supplied.
+    """ Parses an XML file for ignore file patterns. Generates a dictionary
+    object whose key is the name of the group for a collection of ignore
+    patterns. The value in each dictionary is an array of all the ignore
+    pattern objects within that group. Upon any parsing error, no ignore
+    patterns are supplied.
 
-	@param[in] ignoreFile	The directory path and file name to an XML file
-							that contains the ignore patterns to extract.
+    @param[in] ignoreFile    The directory path and file name to an XML file
+                             that contains the ignore patterns to extract.
 
-	@throw ValueError						When the name of a group is reused
-											in the XML file.
+    @throw ValueError       When the name of a group is reused in the XML file.
+    @throw RuntimeError     When the XML file cannot be parsed.
 
-	@throw 	When the XML file cannot be parsed.
+    @return The extracted grouped ignore patterns.
+    """
+    from xml.dom import minidom
+    from xml.parsers.expat import ExpatError
 
-	@return The extracted grouped ignore patterns.
-	"""
-	from xml.dom import minidom
-	from xml.parsers.expat import ExpatError
-
-	ignores = {}
-	try:
-		xmlIgnore = minidom.parse(ignoreFile)
-	except ExpatError as error:
-		raise RuntimeError(error)
-	for group in xmlIgnore.getElementsByTagName('ignores')[0].getElementsByTagName('group'):
-		groupName = group.getAttribute('name')
-		if groupName in ignores:
-			raise ValueError("The group '%s' was already defined." % groupName)
-		else:
-			ignores[groupName] = []
-		for pattern in group.getElementsByTagName('pattern'):
-			ignores[groupName].append(Pattern(
-				pattern.getAttribute('description'),
-				pattern.getAttribute('type'),
-				pattern.firstChild.nodeValue))
-	return ignores
+    ignores = {}
+    try:
+        xmlIgnore = minidom.parse(ignoreFile)
+    except ExpatError as error:
+        raise RuntimeError(error)
+    for group in xmlIgnore.getElementsByTagName(
+            'ignores')[0].getElementsByTagName('group'):
+        groupName = group.getAttribute('name')
+        if groupName in ignores:
+            raise ValueError("The group '%s' was already defined." % groupName)
+        else:
+            ignores[groupName] = []
+        for pattern in group.getElementsByTagName('pattern'):
+            ignores[groupName].append(Pattern(
+                pattern.getAttribute('description'),
+                pattern.getAttribute('type'),
+                pattern.firstChild.nodeValue))
+    return ignores
--- a/src/manager.py	Tue Apr 07 20:03:21 2015 +0200
+++ b/src/manager.py	Fri Feb 19 18:45:37 2016 +0100
@@ -1,23 +1,24 @@
 # -*- coding: utf-8 -*-
-'''*****************************************************************************
-***  This file is part of HgWeb Manager.                                     ***
-***                                                                          ***
-***  Copyright (C) 2014 - 2015                                               ***
-***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Affero General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Affero General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Affero General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*****************************************************************************'''
+'''****************************************************************************
+***  This file is part of HgWeb Manager.                                    ***
+***                                                                         ***
+***  Copyright (C) 2014 - 2016                                              ***
+***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                   ***
+***                                                                         ***
+***  This program is free software: you can redistribute it and/or modify   ***
+***  it under the terms of the GNU Affero General Public License as         ***
+***  published by the Free Software Foundation, either version 3 of the     ***
+***  License, or (at your option) any later version.                        ***
+***                                                                         ***
+***  This program is distributed in the hope that it will be useful, but    ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of             ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                   ***
+***  See the GNU Affero General Public License for more details.            ***
+***                                                                         ***
+***  You should have received a copy of the GNU Affero General Public       ***
+***  License along with this program. If not,                               ***
+***  see <http://www.gnu.org/licenses/>.                                    ***
+****************************************************************************'''
 
 from manrepolock import RepositoryManagerLock
 import config
@@ -27,548 +28,611 @@
 
 
 def plugInEnable(repository, plugInName, scriptFile):
-	""" Enables a plug-in to a managed repository.
+    """ Enables a plug-in to a managed repository.
 
-	@pre The repository must already exist.
+    @pre The repository must already exist.
 
-	@param[in] repository		The targeted repository to add a plug-in to.
-	@param[in] plugInName		The name of the plug-in to add.
-	@param[in] scriptFile		The file path location of the plug-in script.
+    @param[in] repository        The targeted repository to add a plug-in to.
+    @param[in] plugInName        The name of the plug-in to add.
+    @param[in] scriptFile        The file path location of the plug-in script.
 
-	@post The managed repository has it's configuration file changed which
-	enables the supplied plug-in.
+    @post The managed repository has it's configuration file changed which
+    enables the supplied plug-in.
 
-	@throws ValueError		When the repository storage name does not exist.
-	"""
-	from manrepo import RepositoryPlugin
+    @throws ValueError        When the repository storage name does not exist.
+    """
+    from manrepo import RepositoryPlugin
 
-	with RepositoryManagerLock():
-		print "\tEnable plug-in %s for %s" % (plugInName, repository.StorageName)
-		if not __doesRepositoryStorageNameExist(repository):
-			raise ValueError("The repository '%s' does not exist." % repository.StorageName)
+    with RepositoryManagerLock():
+        print "\tEnable plug-in %s for %s" % (plugInName,
+                                              repository.StorageName)
+        if not __doesRepositoryStorageNameExist(repository):
+            raise ValueError("The repository '%s' does not exist." %
+                             repository.StorageName)
 
-		print 'Creating plug-in information ...'
-		plugIn = RepositoryPlugin(plugInName, scriptFile)
-		repository.addPlugIn(plugIn)
-		__writeRepositoryDetails(repository)
+        print 'Creating plug-in information ...'
+        plugIn = RepositoryPlugin(plugInName, scriptFile)
+        repository.addPlugIn(plugIn)
+        __writeRepositoryDetails(repository)
 
 
 def plugInDisable(repository, named):
-	""" Disables a plug-in to a managed repository.
+    """ Disables a plug-in to a managed repository.
 
-	@pre The repository must already exist.
+    @pre The repository must already exist.
 
-	@param[in] repository		The targeted repository to remove a plug-in from.
-	@param[in] named			The name of the plug-in to remove.
+    @param[in] repository       The targeted repository to remove a plug-in
+                                from.
+    @param[in] named            The name of the plug-in to remove.
 
-	@post The managed repository has it's configuration file changed which
-	disables the supplied plug-in.
+    @post The managed repository has it's configuration file changed which
+    disables the supplied plug-in.
 
-	@throws ValueError		When the repository storage name does not exist.
-	"""
-	with RepositoryManagerLock():
-		print "\tDisable plug-in %s for %s" % (named, repository.StorageName)
-		if not __doesRepositoryStorageNameExist(repository):
-			raise ValueError("The repository '%s' does not exist." % repository.StorageName)
+    @throws ValueError        When the repository storage name does not exist.
+    """
+    with RepositoryManagerLock():
+        print "\tDisable plug-in %s for %s" % (named, repository.StorageName)
+        if not __doesRepositoryStorageNameExist(repository):
+            raise ValueError("The repository '%s' does not exist." %
+                             repository.StorageName)
 
-		print 'Removing plug-in information ...'
-		repository.removePlugIn(named)
-		__writeRepositoryDetails(repository)
+        print 'Removing plug-in information ...'
+        repository.removePlugIn(named)
+        __writeRepositoryDetails(repository)
 
 
 def setPlugInSetting(repository, plugIn, named, value):
-	with RepositoryManagerLock():
-		print "\t Setting repository %s's '%s' plug-in setting '%s' to %s" % (repository.StorageName, plugIn, named, value)
-		if not __doesRepositoryStorageNameExist(repository):
-			raise ValueError("The repository '%s' does not exist." % repository.StorageName)
+    with RepositoryManagerLock():
+        print "\t Setting repository %s's '%s' plug-in setting '%s' to %s" % (
+            repository.StorageName, plugIn, named, value)
+        if not __doesRepositoryStorageNameExist(repository):
+            raise ValueError("The repository '%s' does not exist." %
+                             repository.StorageName)
 
-		print 'Modifying plug-in setting ...'
-		repository.setSetting(plugIn, named, value)
-		__writeRepositoryDetails(repository)
+        print 'Modifying plug-in setting ...'
+        repository.setSetting(plugIn, named, value)
+        __writeRepositoryDetails(repository)
 
 
 def create(repository, ignoreGroups, skipCommon):
-	""" Creates a new repository under HgWeb.
+    """ Creates a new repository under HgWeb.
 
-	@pre The repository to create cannot already exist.
+    @pre The repository to create cannot already exist.
 
-	@param[in] repository		The targeted repository to create.
-	@param[in] ignoreGroups		The list of all ignore groups to add.
-	@param[in] skipCommon		A flag that when true indicates the common group
-								should not be added by default.
+    @param[in] repository        The targeted repository to create.
+    @param[in] ignoreGroups      The list of all ignore groups to add.
+    @param[in] skipCommon        A flag that when true indicates the common
+                                 group should not be added by default.
 
-	@post The file system now contains a new directory in the repository path
-	that is the newly generated repository. The new repository is registered
-	in HgWeb to display and is secured to prevent accidental modification.
+    @post The file system now contains a new directory in the repository path
+    that is the newly generated repository. The new repository is registered
+    in HgWeb to display and is secured to prevent accidental modification.
 
-	@throws ValueError		When the repository storage or display name exists.
-	@throws RuntimeError	When the new repository creation encounters an
-							error.
-	"""
-	import os
-	import shutil
-	import stat
+    @throws ValueError      When the repository storage or display name
+                            exists.
+    @throws RuntimeError    When the new repository creation encounters an
+                            error.
+    """
+    import os
+    import shutil
+    import stat
 
-	with RepositoryManagerLock():
-		print "\tAdding repository: %s" % repository.StorageName
-		if __doesRepositoryStorageNameExist(repository):
-			raise ValueError("The repository storage name '%s' already exists." % repository.StorageName)
+    with RepositoryManagerLock():
+        print "\tAdding repository: %s" % repository.StorageName
+        if __doesRepositoryStorageNameExist(repository):
+            raise ValueError("The repository storage name '%s' already exists."
+                             % repository.StorageName)
 
-		if __doesRepositoryDisplayNameExist(repository):
-			raise ValueError("The display name '%s' already exists." % repository.DisplayName)
+        if __doesRepositoryDisplayNameExist(repository):
+            raise ValueError("The display name '%s' already exists." %
+                             repository.DisplayName)
 
-		try:
-			__addRepository(repository)
-			__create_ignores(repository, ignoreGroups, skipCommon)
-		except RuntimeError:
-			__removeRepository(repository)
-			pass
+        try:
+            __addRepository(repository)
+            __create_ignores(repository, ignoreGroups, skipCommon)
+        except RuntimeError:
+            __removeRepository(repository)
+            pass
 
-		try:
-			__writeRepositoryDetails(repository)
-			__registerRepository(repository)
-		except RuntimeError:
-			os.chmod(os.path.join(settings.RepositoryPath, repository.StorageName, '.hg', "hgrc"), stat.S_IWRITE)
-			shutil.rmtree(settings.RepositoryPath + os.sep + repository.StorageName)
-			pass
+        try:
+            __writeRepositoryDetails(repository)
+            __registerRepository(repository)
+        except RuntimeError:
+            os.chmod(os.path.join(settings.RepositoryPath,
+                                  repository.StorageName, '.hg', "hgrc"),
+                     stat.S_IWRITE)
+            shutil.rmtree(settings.RepositoryPath + os.sep +
+                          repository.StorageName)
+            pass
 
 
 def register(repository):
-	""" Connects an existing repository to the mercurial web registry.
+    """ Connects an existing repository to the mercurial web registry.
 
-	@pre The repository to register must already exist.
+    @pre The repository to register must already exist.
 
-	@param[in] repository	The targeted repository to register.
+    @param[in] repository    The targeted repository to register.
 
-	@post The new repository is registered in HgWeb to display and is
-	secured to prevent accidental modification.
+    @post The new repository is registered in HgWeb to display and is
+    secured to prevent accidental modification.
 
-	@throws ValueError		When the repository storage or display name does not
-							exist.
-	@throws RuntimeError	When the new repository registration encounters an
-							error.
-	"""
-	with RepositoryManagerLock():
-		print "\tRegistering the repository: %s" % repository.StorageName
-		if __doesRepositoryStorageNameExist(repository):
-			__registerRepository(repository)
-		else:
-			raise ValueError("The repository '%s' does not exists." % repository.StorageName)
+    @throws ValueError      When the repository storage or display name does
+                            not exist.
+    @throws RuntimeError    When the new repository registration encounters an
+                            error.
+    """
+    with RepositoryManagerLock():
+        print "\tRegistering the repository: %s" % repository.StorageName
+        if __doesRepositoryStorageNameExist(repository):
+            __registerRepository(repository)
+        else:
+            raise ValueError("The repository '%s' does not exists." %
+                             repository.StorageName)
 
 
 def modify(newRepository, currentStorageName, ignoreGroups, skipCommon):
-	""" Changes an existing repository in HgWeb.
+    """ Changes an existing repository in HgWeb.
 
-	@pre The repository to modify must already exist.
+    @pre The repository to modify must already exist.
 
-	@param[in] newRepository		The new values for the repository to
-									modify.
-	@param[in] currentStorageName	The current storage name of the
-									repository to modify.
-	@param[in] ignoreGroups			The list of all ignore groups to add.
-	@param[in] skipCommon			A flag that when true indicates the
-									common group should not be added by
-									default.
+    @param[in] newRepository        The new values for the repository to
+                                    modify.
+    @param[in] currentStorageName   The current storage name of the
+                                    repository to modify.
+    @param[in] ignoreGroups         The list of all ignore groups to add.
+    @param[in] skipCommon           A flag that when true indicates the
+                                    common group should not be added by
+                                    default.
 
-	@post The repository is changed with the requested modifications.
+    @post The repository is changed with the requested modifications.
+
+    @throws ValueError        When the repository storage name does not exist.
+    @throws RuntimeError    When the new repository modification encounters an
+                            error.
+    """
+    from manrepo import Repository
 
-	@throws ValueError		When the repository storage name does not exist.
-	@throws RuntimeError	When the new repository modification encounters an
-							error.
-	"""
-	from manrepo import Repository
+    with RepositoryManagerLock():
+        print "\tModifying repository: %s" % currentStorageName
+        oldRepository = Repository(currentStorageName)
 
-	with RepositoryManagerLock():
-		print "\tModifying repository: %s" % currentStorageName
-		oldRepository = Repository(currentStorageName)
-
-		if not __doesRepositoryStorageNameExist(oldRepository):
-			raise ValueError("The repository '%s' was not found." % oldRepository.StorageName)
+        if not __doesRepositoryStorageNameExist(oldRepository):
+            raise ValueError("The repository '%s' was not found." %
+                             oldRepository.StorageName)
 
-		__unregisterRepository(oldRepository)
-
-		if __doesRepositoryDisplayNameExist(newRepository):
-			__registerRepository(oldRepository)
-			raise ValueError("The display name '%s' already exists." % newRepository.DisplayName)
+        __unregisterRepository(oldRepository)
 
-		# Update renamed repositories
-		if not oldRepository == newRepository:
-			try:
-				__renameStorage(oldRepository, newRepository.StorageName)
-			except RuntimeError:
-				__registerRepository(oldRepository)
-				pass
+        if __doesRepositoryDisplayNameExist(newRepository):
+            __registerRepository(oldRepository)
+            raise ValueError("The display name '%s' already exists." %
+                             newRepository.DisplayName)
 
-		# Fill out the details of about the new repository.
-		try:
-			__writeRepositoryDetails(newRepository)
-			# Update ignore file if requested.
-			if ignoreGroups is not None:
-				__create_ignores(newRepository, ignoreGroups, skipCommon)
-		except RuntimeError:
-			__registerRepository(oldRepository)
-			print "Successfully rolled backed action(s)."
-			pass
+        # Update renamed repositories
+        if not oldRepository == newRepository:
+            try:
+                __renameStorage(oldRepository, newRepository.StorageName)
+            except RuntimeError:
+                __registerRepository(oldRepository)
+                pass
 
-		# Add the new repository to the web registry.
-		__registerRepository(newRepository)
+        # Fill out the details of about the new repository.
+        try:
+            __writeRepositoryDetails(newRepository)
+            # Update ignore file if requested.
+            if ignoreGroups is not None:
+                __create_ignores(newRepository, ignoreGroups, skipCommon)
+        except RuntimeError:
+            __registerRepository(oldRepository)
+            print "Successfully rolled backed action(s)."
+            pass
+
+        # Add the new repository to the web registry.
+        __registerRepository(newRepository)
 
 
 def delete(repository):
-	""" Removes an existing repository.
+    """ Removes an existing repository.
 
-	@pre The repository to remove must already exist.
+    @pre The repository to remove must already exist.
 
-	@param[in] repository	The targeted repository to delete.
+    @param[in] repository    The targeted repository to delete.
 
-	@post The file system no longer contains a directory in the repository
-	path that is the supplied repository. The repository is no longer
-	registered in HgWeb.
+    @post The file system no longer contains a directory in the repository
+    path that is the supplied repository. The repository is no longer
+    registered in HgWeb.
 
-	@throws ValueError		When the repository storage name does not exist.
-	"""
-	with RepositoryManagerLock():
-		if not __doesRepositoryStorageNameExist(repository):
-			raise ValueError("The repository %s was not found." % repository.StorageName)
+    @throws ValueError        When the repository storage name does not exist.
+    """
+    with RepositoryManagerLock():
+        if not __doesRepositoryStorageNameExist(repository):
+            raise ValueError("The repository %s was not found." %
+                             repository.StorageName)
 
-		print "\tRemoving repository: %s" % repository.StorageName
-		__unregisterRepository(repository)
-		__removeRepository(repository)
+        print "\tRemoving repository: %s" % repository.StorageName
+        __unregisterRepository(repository)
+        __removeRepository(repository)
 
 
 def list():
-	""" Outputs a listing of all the known managed repositories """
-	import manrepo
+    """ Outputs a listing of all the known managed repositories """
+    import manrepo
 
-	print "Managed Repositories:"
-	repoCol = manrepo.ManagedCollection()
-	for repo in repoCol.Repositories:
-		print "\t%s (%s)" % (repo.StorageName, repo.DisplayName)
+    print "Managed Repositories:"
+    repoCol = manrepo.ManagedCollection()
+    for repo in repoCol.Repositories:
+        print "\t%s (%s)" % (repo.StorageName, repo.DisplayName)
 
 
-#               Functions For Fulfilling Repository Management               ###
+#             Functions For Fulfilling Repository Management             ###
 
 
 def __create_ignores(repo, ignoreGroups, skipCommon):
-	""" Generates and commits an ignore file to an existing repository.
+    """ Generates and commits an ignore file to an existing repository.
 
-	@pre The repository to create an ignore file must already exist. The list
-	of ignore patterns to use is expected to be in an XML file named
-	"ignores.xml" and be in the hwm-ignore schema.
+    @pre The repository to create an ignore file must already exist. The list
+    of ignore patterns to use is expected to be in an XML file named
+    "ignores.xml" and be in the hwm-ignore schema.
 
-	@param[in] repo				The targeted repository for the ignore file.
-	@param[in] ignoreGroups		The list of all ignore groups to add.
-	@param[in] skipCommon		A flag that when true indicates the common group
-								should not be added by default.
+    @param[in] repo             The targeted repository for the ignore file.
+    @param[in] ignoreGroups     The list of all ignore groups to add.
+    @param[in] skipCommon       A flag that when true indicates the common
+                                group should not be added by default.
 
-	@post The managed repository now has an ignore file committed by the
-	HgWeb manager.
+    @post The managed repository now has an ignore file committed by the
+    HgWeb manager.
 
-	@throws RuntimeError	When the list of ignores does not have a group.
-	"""
-	import os
-	import ignorepo
+    @throws RuntimeError    When the list of ignores does not have a group.
+    """
+    import os
+    import ignorepo
+
+    # Extract Ignore Collection
+    if ignoreGroups is None:
+        ignoreGroups = []
+    ignores = ignorepo.extract(os.path.join(settings.DataPath, 'ignores.xml'))
 
-	# Extract Ignore Collection
-	if ignoreGroups is None:
-		ignoreGroups = []
-	ignores = ignorepo.extract(os.path.join(settings.DataPath, 'ignores.xml'))
+    if skipCommon:
+        del ignores['Common']
+    elif 'common' not in [ignoreGroup.lower() for ignoreGroup in ignoreGroups]:
+        ignoreGroups.append('Common')
 
-	if skipCommon:
-		del ignores['Common']
-	elif 'common' not in [ignoreGroup.lower() for ignoreGroup in ignoreGroups]:
-		ignoreGroups.append('Common')
+    if '+' not in ignoreGroups:
+        for ignoreGroup in ignoreGroups:
+            if not ignoreGroup.lower() in [ignore.lower()
+                                           for ignore in ignores]:
+                raise RuntimeError(
+                    "The list of ignores does not have the '%s' group." %
+                    ignoreGroup)
 
-	if '+' not in ignoreGroups:
-		for ignoreGroup in ignoreGroups:
-			if not ignoreGroup.lower() in [ignore.lower() for ignore in ignores]:
-				raise RuntimeError("The list of ignores does not have the '%s' group." % ignoreGroup)
-
-	ignoreFile = settings.RepositoryPath + os.sep + repo.StorageName + os.sep + '.hgignore'
-	wasCreated = not os.path.isfile(ignoreFile)
-	if wasCreated:
-		print "Creating ignore file ..."
-	else:
-		print "Rewriting ignore file ..."
+    ignoreFile = settings.RepositoryPath + os.sep + repo.StorageName + \
+        os.sep + '.hgignore'
+    wasCreated = not os.path.isfile(ignoreFile)
+    if wasCreated:
+        print "Creating ignore file ..."
+    else:
+        print "Rewriting ignore file ..."
 
-	# Write Ignore File
-	with open(ignoreFile, 'w') as hgIgnore:
-		for groupName, groupPatterns in ignores.items():
-			if '+' not in ignoreGroups and not groupName.lower() in [ignoreGroup.lower() for ignoreGroup in ignoreGroups]:
-				continue
-			hgIgnore.write("#\n#\tIgnore Group: %s\n#" % groupName)
-			# Reverse the sorting order to put the regular expressions first.
-			groupPatterns.sort(key=lambda p: p.Filter, reverse=True)
-			filteringOn = None
-			for pattern in groupPatterns:
-				if pattern.Filter == filteringOn:
-					hgIgnore.write("\n%s\t\t#  %s" % (pattern.Value, pattern.Description))
-				elif filteringOn is None:
-					hgIgnore.write("\nsyntax: %s\n%s\t\t#  %s" % (ignorepo.ignore_syntax_name(pattern.Filter), pattern.Value, pattern.Description))
-				else:
-					hgIgnore.write("\n\nsyntax: %s\n%s\t\t#  %s" % (ignorepo.ignore_syntax_name(pattern.Filter), pattern.Value, pattern.Description))
-				filteringOn = pattern.Filter
-			hgIgnore.write('\n\n')
+    # Write Ignore File
+    with open(ignoreFile, 'w') as hgIgnore:
+        for groupName, groupPatterns in ignores.items():
+            if '+' not in ignoreGroups and not groupName.lower() in \
+                    [ignoreGroup.lower() for ignoreGroup in ignoreGroups]:
+                continue
+            hgIgnore.write("#\n#\tIgnore Group: %s\n#" % groupName)
+            # Reverse the sorting order to put the regular expressions first.
+            groupPatterns.sort(key=lambda p: p.Filter, reverse=True)
+            filteringOn = None
+            for pattern in groupPatterns:
+                if pattern.Filter == filteringOn:
+                    hgIgnore.write("\n%s\t\t#  %s" % (pattern.Value,
+                                                      pattern.Description))
+                elif filteringOn is None:
+                    hgIgnore.write("\nsyntax: %s\n%s\t\t#  %s" % (
+                        ignorepo.ignore_syntax_name(pattern.Filter),
+                        pattern.Value, pattern.Description))
+                else:
+                    hgIgnore.write("\n\nsyntax: %s\n%s\t\t#  %s" %
+                                   (ignorepo.ignore_syntax_name(
+                                       pattern.Filter), pattern.Value,
+                                    pattern.Description))
+                filteringOn = pattern.Filter
+            hgIgnore.write('\n\n')
 
-	if wasCreated:
-		print "Adding generated ignores ..."
-		__addFile(repo, '.hgignore')
+    if wasCreated:
+        print "Adding generated ignores ..."
+        __addFile(repo, '.hgignore')
 
-	print "Committing generated ignores ..."
-	__commitChanges(repo, 'Created generated ignores filter.')
+    print "Committing generated ignores ..."
+    __commitChanges(repo, 'Created generated ignores filter.')
 
 
 def __commitChanges(repo, message):
-	""" Commits all changes in a managed Mercurial repository as the HgWeb
-	manager.
+    """ Commits all changes in a managed Mercurial repository as the HgWeb
+    manager.
 
-	@pre The requested repository must already exist.
+    @pre The requested repository must already exist.
 
-	@param[in] repo		The targeted repository for which to commit.
-	@param[in] message	The text to use as a commit message.
+    @param[in] repo        The targeted repository for which to commit.
+    @param[in] message    The text to use as a commit message.
 
-	@post Upon any error the standard error buffer contains an error message.
+    @post Upon any error the standard error buffer contains an error message.
 
-	@throws RuntimeError	When the added files fail to commit.
-	"""
-	import subprocess
-	import os
+    @throws RuntimeError    When the added files fail to commit.
+    """
+    import subprocess
+    import os
 
-	statusCode = subprocess.call([settings.HgCommand, '--repository', settings.RepositoryPath + os.sep + repo.StorageName, 'commit', '--message', message, '--user', settings.HgUser + ' - HgWeb Manager'])
+    statusCode = subprocess.call([settings.HgCommand, '--repository',
+                                  settings.RepositoryPath + os.sep +
+                                  repo.StorageName, 'commit', '--message',
+                                  message, '--user', settings.HgUser +
+                                  ' - HgWeb Manager'])
 
-	# Zero being a successful commit and one being nothing changed.
-	if not ((0 == statusCode) or (1 == statusCode)):
-		raise RuntimeError("Failed to commit files. Status code: " + statusCode)
+    # Zero being a successful commit and one being nothing changed.
+    if not ((0 == statusCode) or (1 == statusCode)):
+        raise RuntimeError("Failed to commit files. Status code: " +
+                           statusCode)
 
 
 def __addFile(repo, fileName):
-	""" Marks a file as added in a managed Mercurial repository.
+    """ Marks a file as added in a managed Mercurial repository.
 
-	@pre The requested repository must already exist.
+    @pre The requested repository must already exist.
 
-	@param[in] repo			The targeted repository for which to add the file.
-	@param[in] fileName		The directory path and the file name to add
-							relative to the base of the repository.
+    @param[in] repo         The targeted repository for which to add the
+                            file.
+    @param[in] fileName     The directory path and the file name to add
+                            relative to the base of the repository.
 
-	@post Upon any error the standard error buffer contains an error message.
+    @post Upon any error the standard error buffer contains an error message.
 
-	@throws RuntimeError	When the the news files fail to be added.
-	"""
-	import subprocess
-	import os
+    @throws RuntimeError    When the the news files fail to be added.
+    """
+    import subprocess
+    import os
 
-	statusCode = subprocess.call([settings.HgCommand, '--repository', settings.RepositoryPath + os.sep + repo.StorageName, 'add', settings.RepositoryPath + os.sep + repo.StorageName + os.sep + fileName])
+    statusCode = subprocess.call([settings.HgCommand, '--repository',
+                                  settings.RepositoryPath + os.sep +
+                                  repo.StorageName, 'add',
+                                  settings.RepositoryPath + os.sep +
+                                  repo.StorageName + os.sep + fileName])
 
-	# Zero being a successful commit and one being nothing to add.
-	if not ((0 == statusCode) or (1 == statusCode)):
-		raise RuntimeError("Failed to commit files. Status code: " + statusCode)
+    # Zero being a successful commit and one being nothing to add.
+    if not ((0 == statusCode) or (1 == statusCode)):
+        raise RuntimeError("Failed to commit files. Status code: " +
+                           statusCode)
 
 
 def __renameStorage(oldRepo, newName):
-	""" Changes the storage name of an existing repository.
+    """ Changes the storage name of an existing repository.
 
-	@param[in] oldRepo		The existing repository to whose storage name is
-							expected to be changed.
-	@param[in] newName		The new storage name for the repository.
+    @param[in] oldRepo        The existing repository to whose storage name is
+                            expected to be changed.
+    @param[in] newName        The new storage name for the repository.
 
-	@throws ValueError	When the supplied new storage name already exists.
-	"""
-	import os
-	import shutil
+    @throws ValueError    When the supplied new storage name already exists.
+    """
+    import os
+    import shutil
 
-	if not oldRepo.StorageName == newName:
-		print "Renaming repository %s to %s ..." % (oldRepo.StorageName, newName)
-		if os.path.isdir(settings.RepositoryPath + os.sep + newName):
-			raise ValueError("Cannot rename the existing repository '%s' because the name '%s' already exists." % (oldRepo.StorageName, newName))
-		shutil.move(settings.RepositoryPath + os.sep + oldRepo.StorageName, settings.RepositoryPath + os.sep + newName)
+    if not oldRepo.StorageName == newName:
+        print "Renaming repository %s to %s ..." % (oldRepo.StorageName,
+                                                    newName)
+        if os.path.isdir(settings.RepositoryPath + os.sep + newName):
+            raise ValueError(
+                "Cannot rename the existing repository '%s' because the"
+                " name '%s' already exists." % (oldRepo.StorageName, newName))
+        shutil.move(settings.RepositoryPath + os.sep + oldRepo.StorageName,
+                    settings.RepositoryPath + os.sep + newName)
 
 
 def __doesRepositoryStorageNameExist(repo):
-	""" Checks to see if a repository storage name exists.
+    """ Checks to see if a repository storage name exists.
+
+    @param[in] repo        The targeted repository for which to check.
 
-	@param[in] repo		The targeted repository for which to check.
+    @return Gives true when it exists, false else-wise.
+    """
+    import os
 
-	@return Gives true when it exists, false else-wise.
-	"""
-	import os
-
-	if (repo is None) or (repo.StorageName is None):
-		return False
-	elif os.path.isdir(settings.RepositoryPath + os.sep + repo.StorageName + os.sep + '.hg'):
-		return True
-	else:
-		return False
+    if (repo is None) or (repo.StorageName is None):
+        return False
+    elif os.path.isdir(settings.RepositoryPath + os.sep + repo.StorageName +
+                       os.sep + '.hg'):
+        return True
+    else:
+        return False
 
 
 def __doesRepositoryDisplayNameExist(repo):
-	""" Checks to see if a repository display name exists.
+    """ Checks to see if a repository display name exists.
 
-	@param[in] repo		The targeted repository for which to check.
+    @param[in] repo        The targeted repository for which to check.
 
-	@return Gives true when it exists, false else-wise.
-	"""
-	from manrepo import ManagedCollection
+    @return Gives true when it exists, false else-wise.
+    """
+    from manrepo import ManagedCollection
 
-	if (repo is None) or (repo.StorageName is None) or (repo.DisplayName is None):
-		return False
+    if (repo is None) or (repo.StorageName is None) or\
+            (repo.DisplayName is None):
+        return False
 
-	repoCol = ManagedCollection()
-	for testRepo in repoCol.Repositories:
-		if (testRepo.DisplayName is not None) and (not testRepo == repo) and (testRepo.DisplayName.lower() == repo.DisplayName.lower()):
-			return True
-	return False
+    repoCol = ManagedCollection()
+    for testRepo in repoCol.Repositories:
+        if (testRepo.DisplayName is not None) and (not testRepo == repo) and \
+                (testRepo.DisplayName.lower() == repo.DisplayName.lower()):
+            return True
+    return False
 
 
 def __unregisterRepository(repo):
-	""" Removes the registration of the supplied repository.
+    """ Removes the registration of the supplied repository.
+
+    @param[in] repo        The targeted repository for which to unregister.
 
-	@param[in] repo		The targeted repository for which to unregister.
+    @post The HgWeb configuration file does not contain the repository details
+    and is returned to a read-only state. Upon any error the standard error
+    buffer contains an error message.
 
-	@post The HgWeb configuration file does not contain the repository details
-	and is returned to a read-only state. Upon any error the standard error
-	buffer contains an error message.
-
-	@throws RuntimeError	When the web path is missing the configuration file.
-	@throws RuntimeError	When the configuration file does not contain a path
-							section.
-	"""
-	from ConfigParser import SafeConfigParser
-	import os
+    @throws RuntimeError    When the web path is missing the configuration
+                            file.
+    @throws RuntimeError    When the configuration file does not contain a path
+                            section.
+    """
+    from ConfigParser import SafeConfigParser
+    import os
 
-	parser = SafeConfigParser()
-	if not parser.read(settings.HgWebPath + os.sep + 'hgweb.config'):
-		raise RuntimeError("Failed to locate HgWeb configuration file.")
+    parser = SafeConfigParser()
+    if not parser.read(settings.HgWebPath + os.sep + 'hgweb.config'):
+        raise RuntimeError("Failed to locate HgWeb configuration file.")
 
-	if parser.has_section('paths'):
-		if parser.has_option('paths', repo.StorageName):
-			print "Unregistering repository ..."
-			parser.remove_option('paths', repo.StorageName)
-			with open(settings.HgWebPath + os.sep + 'hgweb.config', 'wb') as configfile:
-				parser.write(configfile)
-		else:
-			print "The repository already is unregistered."
-	else:
-		raise RuntimeError("The HgWeb configuration file does not have a paths section! Failed to unregister repository.")
+    if parser.has_section('paths'):
+        if parser.has_option('paths', repo.StorageName):
+            print "Unregistering repository ..."
+            parser.remove_option('paths', repo.StorageName)
+            with open(settings.HgWebPath + os.sep + 'hgweb.config',
+                      'wb') as configfile:
+                parser.write(configfile)
+        else:
+            print "The repository already is unregistered."
+    else:
+        raise RuntimeError('The HgWeb configuration file does not have a '
+                           'paths section! Failed to unregister repository.')
 
 
 def __removeRepository(repo):
-	""" Removes an existing Mercurial repository.
+    """ Removes an existing Mercurial repository.
 
-	@pre The requested repository to delete must already exist.
+    @pre The requested repository to delete must already exist.
 
-	@param[in] repo		The targeted repository for which to delete.
+    @param[in] repo        The targeted repository for which to delete.
 
-	@post Upon any error the standard error buffer contains an error message.
-	"""
-	import shutil
-	import os
-	import stat
+    @post Upon any error the standard error buffer contains an error message.
+    """
+    import shutil
+    import os
+    import stat
 
-	print "Removing repository directories ..."
-	try:
-		os.chmod(settings.RepositoryPath + os.sep + repo.StorageName + os.sep + '.hg' + os.sep + "hgrc", stat.S_IWRITE)
-	except OSError as e:
-		# If it's anything but the "No such file or directory", notify the user.
-		if not 2 == e.errno:
-			pass
-	shutil.rmtree(settings.RepositoryPath + os.sep + repo.StorageName)
+    print "Removing repository directories ..."
+    try:
+        os.chmod(settings.RepositoryPath + os.sep + repo.StorageName +
+                 os.sep + '.hg' + os.sep + "hgrc", stat.S_IWRITE)
+    except OSError as e:
+        # If it's anything but the "No such file or directory",
+        # notify the user.
+        if not 2 == e.errno:
+            pass
+    shutil.rmtree(settings.RepositoryPath + os.sep + repo.StorageName)
 
 
 def __addRepository(repo):
-	""" Initialises a new Mercurial repository.
+    """ Initialises a new Mercurial repository.
 
-	@pre The requested repository to create cannot already exist.
+    @pre The requested repository to create cannot already exist.
 
-	@param[in] repo	The targeted repository for which to create.
+    @param[in] repo    The targeted repository for which to create.
 
-	@post Upon any error the standard error buffer contains an error message.
+    @post Upon any error the standard error buffer contains an error message.
 
-	@throws ValueError		When the storage name is missing.
-	@throws RuntimeError	When the initialisation call fails.
-	"""
-	import subprocess
-	import os
+    @throws ValueError        When the storage name is missing.
+    @throws RuntimeError    When the initialisation call fails.
+    """
+    import subprocess
+    import os
 
-	print "Initialising repository directory ..."
-	if repo.StorageName is None:
-		raise ValueError('Cannot create a managed repository without a storage name.')
-	statusCode = subprocess.call([settings.HgCommand, 'init', settings.RepositoryPath + os.sep + repo.StorageName])
-	if not (0 == statusCode):
-		raise RuntimeError("Failed to initialise repository. Status code: " + statusCode)
+    print "Initialising repository directory ..."
+    if repo.StorageName is None:
+        raise ValueError(
+            'Cannot create a managed repository without a storage name.')
+    statusCode = subprocess.call([settings.HgCommand, 'init',
+                                  settings.RepositoryPath + os.sep +
+                                  repo.StorageName])
+    if not (0 == statusCode):
+        raise RuntimeError('Failed to initialise repository. Status code: ' +
+                           statusCode)
 
 
 def __writeRepositoryDetails(repo):
-	""" Writes the details of a repository to the repository's
-	configuration file.
+    """ Writes the details of a repository to the repository's
+    configuration file.
 
-	@param[in] repo		The targeted repository for which to write the
-						configuration details.
+    @param[in] repo        The targeted repository for which to write the
+                        configuration details.
 
-	@post The HgWeb configuration file contains the new repository details and
-	is returned to a read-only state.
-	"""
-	import os
-	import stat
-	import sys
+    @post The HgWeb configuration file contains the new repository details and
+    is returned to a read-only state.
+    """
+    import os
+    import stat
+    import sys
 
-	print "Saving repository configuration details ..."
-	config = settings.RepositoryPath + os.sep + repo.StorageName + os.sep + '.hg' + os.sep + 'hgrc'
+    print "Saving repository configuration details ..."
+    config = settings.RepositoryPath + os.sep + repo.StorageName + os.sep + \
+        '.hg' + os.sep + 'hgrc'
 
-	if os.path.exists(config):
-		hgrcMode = os.stat(config)[stat.ST_MODE]
-		os.chmod(config, hgrcMode | stat.S_IWRITE)
-	else:
-		hgrcMode = stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH
-	repo.save()
-	# Ensure the repository details isn't accidentally modified.
-	os.chmod(config, hgrcMode & (~stat.S_IWUSR & ~stat.S_IWGRP & ~stat.S_IWOTH))
+    if os.path.exists(config):
+        hgrcMode = os.stat(config)[stat.ST_MODE]
+        os.chmod(config, hgrcMode | stat.S_IWRITE)
+    else:
+        hgrcMode = stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH
+    repo.save()
+    # Ensure the repository details isn't accidentally modified.
+    os.chmod(config, hgrcMode & (~stat.S_IWUSR & ~stat.S_IWGRP &
+                                 ~stat.S_IWOTH))
 
-	# Ensure the repository isn't accidentally deleted, moved, or blocked in Windows.
-	if "win32" == sys.platform:
-		__guardWindowsRepository(repo)
-		print 'Secured repository store in Windows.'
+    # Ensure the repository isn't accidentally deleted, moved, or
+    # blocked in Windows.
+    if "win32" == sys.platform:
+        __guardWindowsRepository(repo)
+        print 'Secured repository store in Windows.'
 
 
 def __guardWindowsRepository(repo):
-	""" Guards the supplied repository for a repository on a Windows system.
+    """ Guards the supplied repository for a repository on a Windows system.
+
+    @param[in] repo    The targeted repository for which to secure.
+    """
+    import subprocess
+    import os
 
-	@param[in] repo	The targeted repository for which to secure.
-	"""
-	import subprocess
-	import os
+    print 'Securing for Windows ...'
+    status = subprocess.call(['attrib.exe', '+H', '+I', '+S',
+                              settings.RepositoryPath + os.sep +
+                              repo.StorageName + os.sep + '.hg'])
 
-	print 'Securing for Windows ...'
-	status = subprocess.call(['attrib.exe', '+H', '+I', '+S', settings.RepositoryPath + os.sep + repo.StorageName + os.sep + '.hg'])
-
-	if not (0 == status):
-		raise RuntimeError("Failed to secure repository store for windows. Status code: " + status)
+    if not (0 == status):
+        raise RuntimeError('Failed to secure repository store for '
+                           'windows. Status code: ' + status)
 
 
 def __registerRepository(repo):
-	""" Adds the registration details of the repository.
+    """ Adds the registration details of the repository.
 
-	@param[in] repo		The targeted repository for which to register in HgWeb.
+    @param[in] repo        The targeted repository for which to register
+                           in HgWeb.
 
-	@post The HgWeb configuration file contains the new repository details and
-	is returned to a read-only state. Upon any error the standard error
-	buffer contains an error message.
+    @post The HgWeb configuration file contains the new repository details and
+    is returned to a read-only state. Upon any error the standard error
+    buffer contains an error message.
 
-	@throws RuntimeError	When the HgWeb configuration file cannot be found.
-	@throws ValueError		When the supplied repository is already registered.
-	"""
-	from ConfigParser import SafeConfigParser
-	import os
+    @throws RuntimeError    When the HgWeb configuration file cannot be found.
+    @throws ValueError      When the supplied repository is already registered.
+    """
+    from ConfigParser import SafeConfigParser
+    import os
 
-	parser = SafeConfigParser()
-	if not parser.read(settings.HgWebPath + os.sep + 'hgweb.config'):
-		raise RuntimeError("Failed to locate HgWeb configuration file.")
+    parser = SafeConfigParser()
+    if not parser.read(settings.HgWebPath + os.sep + 'hgweb.config'):
+        raise RuntimeError("Failed to locate HgWeb configuration file.")
 
-	if parser.has_section('paths'):
-		if parser.has_option('paths', repo.StorageName):
-			raise ValueError("The repository already is registered.")
-	else:
-		parser.add_section('paths')
-	print "Registering repository ..."
-	parser.set('paths', repo.StorageName, settings.RepositoryPath + os.sep + repo.StorageName)
-	with open(settings.HgWebPath + os.sep + 'hgweb.config', 'wb') as configfile:
-		parser.write(configfile)
+    if parser.has_section('paths'):
+        if parser.has_option('paths', repo.StorageName):
+            raise ValueError("The repository already is registered.")
+    else:
+        parser.add_section('paths')
+    print "Registering repository ..."
+    parser.set('paths', repo.StorageName, settings.RepositoryPath +
+               os.sep + repo.StorageName)
+    with open(settings.HgWebPath + os.sep + 'hgweb.config',
+              'wb') as configfile:
+        parser.write(configfile)
--- a/src/manrepo.py	Tue Apr 07 20:03:21 2015 +0200
+++ b/src/manrepo.py	Fri Feb 19 18:45:37 2016 +0100
@@ -1,400 +1,420 @@
 # -*- coding: utf-8 -*-
-'''*****************************************************************************
-***  This file is part of HgWeb Manager.                                     ***
-***                                                                          ***
-***  Copyright (C) 2014 - 2015                                               ***
-***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Affero General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Affero General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Affero General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*****************************************************************************'''
+'''****************************************************************************
+***  This file is part of HgWeb Manager.                                    ***
+***                                                                         ***
+***  Copyright (C) 2014 - 2016                                              ***
+***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                   ***
+***                                                                         ***
+***  This program is free software: you can redistribute it and/or modify   ***
+***  it under the terms of the GNU Affero General Public License as         ***
+***  published by the Free Software Foundation, either version 3 of the     ***
+***  License, or (at your option) any later version.                        ***
+***                                                                         ***
+***  This program is distributed in the hope that it will be useful, but    ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of             ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                   ***
+***  See the GNU Affero General Public License for more details.            ***
+***                                                                         ***
+***  You should have received a copy of the GNU Affero General Public       ***
+***  License along with this program. If not,                               ***
+***  see <http://www.gnu.org/licenses/>.                                    ***
+****************************************************************************'''
 
 from manager import settings
 
 
 class Repository(object):
-	""" Describes the properties of a repository managed by HWM and served up
-	by HgWeb.
-	"""
+    """ Describes the properties of a repository managed by HWM and served up
+    by HgWeb.
+    """
 
-	# The directory name of the managed repository.
-	__storageName = None
-	# The displayed web-site name of the managed repository.
-	__displayName = None
-	# The displayed web-site description of the managed repository.
-	__description = None
-	# The displayed web-site contact information of the managed repository.
-	__contact = None
-	# The Mercurial repository interface.
-	__repo = None
-	# The collection of plug-ins enabled for a repository.
-	__plugIns = None
+    # The directory name of the managed repository.
+    __storageName = None
+    # The displayed web-site name of the managed repository.
+    __displayName = None
+    # The displayed web-site description of the managed repository.
+    __description = None
+    # The displayed web-site contact information of the managed repository.
+    __contact = None
+    # The Mercurial repository interface.
+    __repo = None
+    # The collection of plug-ins enabled for a repository.
+    __plugIns = None
 
-	@property
-	def StorageName(self):
-		""" Gets the name of the directory where the managed repository is located. """
-		return self.__storageName
+    @property
+    def StorageName(self):
+        """ Gets the name of the directory where the managed repository
+        is located. """
+        return self.__storageName
 
-	@property
-	def DisplayName(self):
-		""" Gets the name to display for the managed repository. """
-		return self.__displayName
+    @property
+    def DisplayName(self):
+        """ Gets the name to display for the managed repository. """
+        return self.__displayName
 
-	@DisplayName.setter
-	def DisplayName(self, value):
-		""" Sets the name of the managed repository to display. """
-		self.__displayName = value
+    @DisplayName.setter
+    def DisplayName(self, value):
+        """ Sets the name of the managed repository to display. """
+        self.__displayName = value
+
+    @property
+    def Description(self):
+        """ Gets the description of the managed repository. """
+        return self.__description
 
-	@property
-	def Description(self):
-		""" Gets the description of the managed repository. """
-		return self.__description
+    @Description.setter
+    def Description(self, value):
+        """ Sets the description of the managed repository to display. """
+        self.__description = value
 
-	@Description.setter
-	def Description(self, value):
-		""" Sets the description of the managed repository to display. """
-		self.__description = value
+    @property
+    def Contact(self):
+        """ Gets the contact point for the managed repository. """
+        return self.__contact
 
-	@property
-	def Contact(self):
-		""" Gets the contact point for the managed repository. """
-		return self.__contact
+    @Contact.setter
+    def Contact(self, value):
+        """ Sets the contact point for the managed repository. """
+        self.__contact = value
 
-	@Contact.setter
-	def Contact(self, value):
-		""" Sets the contact point for the managed repository. """
-		self.__contact = value
+    @property
+    def PlugIns(self):
+        """ Gets the collection of enabled plug-ins for the managed
+        repository. """
+        return self.__plugIns
 
-	@property
-	def PlugIns(self):
-		""" Gets the collection of enabled plug-ins for the managed repository. """
-		return self.__plugIns
+    def __init__(self, repoName=None):
+        """ Initialises the object with the values from a managed repository
 
-	def __init__(self, repoName=None):
-		""" Initialises the object with the values from a managed repository
-
-		@param[in] repoName		The storage name of the managed repository
-								to load.
-		"""
-		from mercurial import ui, hg, error
-		import os
+        @param[in] repoName        The storage name of the managed repository
+                                   to load.
+        """
+        from mercurial import ui, hg, error
+        import os
 
-		self.__storageName = repoName
-		if repoName:
-			try:
-				self.__repo = hg.repository(ui.ui(), settings.RepositoryPath + os.sep + self.__storageName)
-				self.__displayName = self.__repo.ui.config('web', 'name', default=None)
-				self.__description = self.__repo.ui.config('web', 'description', default=None)
-				self.__contact = self.__repo.ui.config('web', 'contact', default=None)
-				self.__plugIns = []
-				plugInList = self.__repo.ui.configitems('extensions')
-				for plugIn in plugInList:
-					self.__plugIns.append(RepositoryPlugin(plugIn[0], plugIn[1], self.__repo.ui.configitems(plugIn[0])))
-			except error.RepoError:
-				self.__plugIns = []
-				pass
+        self.__storageName = repoName
+        if repoName:
+            try:
+                self.__repo = hg.repository(ui.ui(), settings.RepositoryPath +
+                                            os.sep + self.__storageName)
+                self.__displayName = self.__repo.ui.config('web', 'name',
+                                                           default=None)
+                self.__description = self.__repo.ui.config('web',
+                                                           'description',
+                                                           default=None)
+                self.__contact = self.__repo.ui.config('web', 'contact',
+                                                       default=None)
+                self.__plugIns = []
+                plugInList = self.__repo.ui.configitems('extensions')
+                for plugIn in plugInList:
+                    self.__plugIns.append(RepositoryPlugin(
+                        plugIn[0],
+                        plugIn[1],
+                        self.__repo.ui.configitems(plugIn[0])))
+            except error.RepoError:
+                self.__plugIns = []
+                pass
 
-	def __eq__(self, other):
-		""" Determines if two repositories are the same repository.
+    def __eq__(self, other):
+        """ Determines if two repositories are the same repository.
 
-		@param[in] other	The repository on the right-hand-side of the
-							equality operator to compare against.
+        @param[in] other    The repository on the right-hand-side of the
+                            equality operator to compare against.
 
-		@return Gives true when both repositories represent the same one,
-		else-wise gives false.
-		"""
-		return self.__storageName == other.__storageName
+        @return Gives true when both repositories represent the same one,
+        else-wise gives false.
+        """
+        return self.__storageName == other.__storageName
 
-	def save(self):
-		""" Commits the repository detail properties to the repository
-		configuration file.
+    def save(self):
+        """ Commits the repository detail properties to the repository
+        configuration file.
 
-		@throws IOError		When the configuration file for the repository
-							fails to be written.
-		"""
-		import os
+        @throws IOError        When the configuration file for the repository
+                            fails to be written.
+        """
+        import os
 
-		with open(settings.RepositoryPath + os.sep + self.__storageName + os.sep + '.hg' + os.sep + 'hgrc', 'w') as hgrc:
-			#{ Repository Information Section
+        with open(settings.RepositoryPath + os.sep + self.__storageName +
+                  os.sep + '.hg' + os.sep + 'hgrc', 'w') as hgrc:
+            # { Repository Information Section
 
-			hgrc.write('[web]\n')
-			if self.DisplayName is None:
-				hgrc.write('name = ' + self.StorageName + '\n')
-			else:
-				hgrc.write('name = ' + self.DisplayName + '\n')
+            hgrc.write('[web]\n')
+            if self.DisplayName is None:
+                hgrc.write('name = ' + self.StorageName + '\n')
+            else:
+                hgrc.write('name = ' + self.DisplayName + '\n')
 
-			if self.Description is not None:
-				hgrc.write('description = ' + self.Description + '\n')
+            if self.Description is not None:
+                hgrc.write('description = ' + self.Description + '\n')
 
-			if self.Contact is not None:
-				hgrc.write('contact = ' + self.Contact + '\n')
+            if self.Contact is not None:
+                hgrc.write('contact = ' + self.Contact + '\n')
 
-			#} Repository Information Section
+            # } Repository Information Section
+
+            # { Plug-in Section
 
-			#{ Plug-in Section
+            if len(self.PlugIns) > 0:
+                hgrc.write('\n[extensions]\n')
+                for plugIn in self.PlugIns:
+                    if plugIn.scriptFile is None:
+                        hgrc.write(plugIn.name + ' =\n')
+                    else:
+                        hgrc.write(plugIn.name + ' = ' + plugIn.scriptFile +
+                                   '\n')
 
-			if len(self.PlugIns) > 0:
-				hgrc.write('\n[extensions]\n')
-				for plugIn in self.PlugIns:
-					if plugIn.scriptFile is None:
-						hgrc.write(plugIn.name + ' =\n')
-					else:
-						hgrc.write(plugIn.name + ' = ' + plugIn.scriptFile + '\n')
-
-			#} Plug-in Section
+                # { Plug-in Settings Section
 
-			#{ Plug-in Settings Section
+                for plugIn in self.PlugIns:
+                    if len(plugIn.settings) > 0:
+                        hgrc.write("\n[%s]" % plugIn.name)
+                        for setting in plugIn.settings:
+                            hgrc.write("\n%s = %s" % (setting.name,
+                                                      setting.value))
 
-			for plugIn in self.PlugIns:
-				if len(plugIn.settings) > 0:
-					hgrc.write("\n[%s]" % plugIn.name)
-					for setting in plugIn.settings:
-						hgrc.write("\n%s = %s" % (setting.name, setting.value))
+                # } Plug-in Settings Section
 
-			#} Plug-in Settings Section
+            # } Plug-in Section
 
-		self = Repository(self.StorageName)  # Needed for when repositories are re-named.
+        # NOTE: Needed for when repositories are re-named.
+        self = Repository(self.StorageName)
 
-	def __str__(self):
-		""" Converts the object contents into a human-friendly string. """
-		repo = "%s\n\tDisplay: %s\n\tDescription: %s\n\tContact: %s" % (self.StorageName, self.DisplayName, self.Description, self.Contact)
-		if len(self.PlugIns) > 0:
-			repo = repo + "\n\tPlug-ins:"
-			for plugIn in self.PlugIns:
-				repo = repo + "\n\t\t%s" % plugIn
-		return repo
+    def __str__(self):
+        """ Converts the object contents into a human-friendly string. """
+        repo = "%s\n\tDisplay: %s\n\tDescription: %s\n\tContact: %s" % (
+            self.StorageName, self.DisplayName, self.Description, self.Contact)
+        if len(self.PlugIns) > 0:
+            repo = repo + "\n\tPlug-ins:"
+            for plugIn in self.PlugIns:
+                repo = repo + "\n\t\t%s" % plugIn
+        return repo
 
-	def addPlugIn(self, plugIn):
-		""" Makes a plug-in in a repository enabled.
+    def addPlugIn(self, plugIn):
+        """ Makes a plug-in in a repository enabled.
 
-		@param[in] plugIn	The plug-in that is to be enabled.
+        @param[in] plugIn    The plug-in that is to be enabled.
 
-		@post The object now has the supplied plug-in as being enabled.
+        @post The object now has the supplied plug-in as being enabled.
 
-		@throws ValueError		When the supplied plug-in is already enabled.
-		"""
-		if plugIn not in self.PlugIns:
-			self.__plugIns.append(plugIn)
-		else:
-			raise ValueError("The plug-in '%s' is already enabled." % plugIn.name)
+        @throws ValueError        When the supplied plug-in is already enabled.
+        """
+        if plugIn not in self.PlugIns:
+            self.__plugIns.append(plugIn)
+        else:
+            raise ValueError("The plug-in '%s' is already enabled." %
+                             plugIn.name)
 
-	def removePlugIn(self, named):
-		""" Makes a plug-in in a repository disabled.
+    def removePlugIn(self, named):
+        """ Makes a plug-in in a repository disabled.
 
-		@param[in] named	The name of the plug-in that is to be disabled.
+        @param[in] named    The name of the plug-in that is to be disabled.
 
-		@post The object no longer has the supplied plug-in as being enabled.
+        @post The object no longer has the supplied plug-in as being enabled.
 
-		@throws ValueError		When the supplied plug-in is already disabled.
-		"""
-		for plugIn in self.PlugIns:
-			if named == plugIn.name:
-				self.__plugIns.remove(plugIn)
-				return
-		raise ValueError("The plug-in '%s' is already disabled." % named)
+        @throws ValueError        When the supplied plug-in is already
+                                  disabled.
+        """
+        for plugIn in self.PlugIns:
+            if named == plugIn.name:
+                self.__plugIns.remove(plugIn)
+                return
+        raise ValueError("The plug-in '%s' is already disabled." % named)
 
-	def setSetting(self, plugInName, name, value):
-		""" Set's the setting of a plug-in
-		@details When the supplied value is None, the setting is removed.
+    def setSetting(self, plugInName, name, value):
+        """ Set's the setting of a plug-in
+        @details When the supplied value is None, the setting is removed.
 
-		@param[in] plugInName		The name of the plug-in whose setting is
-									being set.
-		@param[in] name				The name of the setting being set.
-		@param[in] value			The value for the setting.
+        @param[in] plugInName        The name of the plug-in whose setting is
+                                    being set.
+        @param[in] name                The name of the setting being set.
+        @param[in] value            The value for the setting.
 
-		@post The setting for the plug-in is modified to the supplied value.
+        @post The setting for the plug-in is modified to the supplied value.
 
-		@throws ValueError	When the supplied plug-in name is not enabled.
-		"""
-		for plugIn in self.PlugIns:
-			if plugInName == plugIn.name:
-				plugInIndex = self.PlugIns.index(plugIn)
-				self.__plugIns[plugInIndex].setPlugInSetting(name, value)
-				return
-		raise ValueError("The plug-in '%s' is not enabled." % plugInName)
+        @throws ValueError    When the supplied plug-in name is not enabled.
+        """
+        for plugIn in self.PlugIns:
+            if plugInName == plugIn.name:
+                plugInIndex = self.PlugIns.index(plugIn)
+                self.__plugIns[plugInIndex].setPlugInSetting(name, value)
+                return
+        raise ValueError("The plug-in '%s' is not enabled." % plugInName)
 
 
 class RepositoryPlugin(object):
-	""" Manages a plug-in for a repository. """
-	class PluginSetting(object):
-		""" Manages a plug-in setting found inside a repository. """
+    """ Manages a plug-in for a repository. """
+    class PluginSetting(object):
+        """ Manages a plug-in setting found inside a repository. """
 
-		# The name of the plug-in setting.
-		__name = None
-		# The setting value for the of the plug-in option.
-		__value = None
+        # The name of the plug-in setting.
+        __name = None
+        # The setting value for the of the plug-in option.
+        __value = None
 
-		@property
-		def name(self):
-			""" Accessor to the option name for a plug-in. """
-			return self.__name
+        @property
+        def name(self):
+            """ Accessor to the option name for a plug-in. """
+            return self.__name
 
-		@property
-		def value(self):
-			""" Accessor to the option value for a plug-in option. """
-			return self.__value
+        @property
+        def value(self):
+            """ Accessor to the option value for a plug-in option. """
+            return self.__value
 
-		@value.setter
-		def value(self, value):
-			""" Mutator to the option value for a plug-in option. """
-			self.__value = value
+        @value.setter
+        def value(self, value):
+            """ Mutator to the option value for a plug-in option. """
+            self.__value = value
 
-		def __init__(self, name, value=None):
-			""" Initialises a plug-in setting.
+        def __init__(self, name, value=None):
+            """ Initialises a plug-in setting.
 
-			@param[in] name		The name of the plug-in setting option.
-			@param[in] name		The value for the plug-in setting option.
+            @param[in] name        The name of the plug-in setting option.
+            @param[in] name        The value for the plug-in setting option.
 
-			@post The object is ready for use.
-			"""
-			self.__name = name
-			self.__value = value
+            @post The object is ready for use.
+            """
+            self.__name = name
+            self.__value = value
 
-		def __str__(self):
-			""" Constructs a string representation of the object and it's values.
+        def __str__(self):
+            """ Constructs a string representation of the object and it's values.
 
-			@return The representation in the form name => value
-			"""
-			return "%s => %s" % (self.name, self.value)
-	# The name of a repository plug-in.
-	__name = None
-	# The path and file-name of the script for the repository plug-in.
-	__scriptFile = None
-	# The supplied option settings for the repository plug-in.
-	__settings = None
+            @return The representation in the form name => value
+            """
+            return "%s => %s" % (self.name, self.value)
+    # The name of a repository plug-in.
+    __name = None
+    # The path and file-name of the script for the repository plug-in.
+    __scriptFile = None
+    # The supplied option settings for the repository plug-in.
+    __settings = None
 
-	@property
-	def name(self):
-		""" The accessor to the name of a repository plug-in. """
-		return self.__name
+    @property
+    def name(self):
+        """ The accessor to the name of a repository plug-in. """
+        return self.__name
 
-	@property
-	def scriptFile(self):
-		""" The accessor to the path and file-name of the script for the
-		repository plug-in.
-		"""
-		return self.__scriptFile
+    @property
+    def scriptFile(self):
+        """ The accessor to the path and file-name of the script for the
+        repository plug-in.
+        """
+        return self.__scriptFile
 
-	@property
-	def settings(self):
-		""" The accessor to the supplied option settings for the repository
-		plug-in.
-		"""
-		return self.__settings
+    @property
+    def settings(self):
+        """ The accessor to the supplied option settings for the repository
+        plug-in.
+        """
+        return self.__settings
 
-	def __init__(self, name, scriptFile=None, plugInSettings=[]):
-		""" Initialises a plug-in.
-		@details The supplied plug-in setting must be a key-value pair
-		co-responding to the plug-in option name and it's value respectively.
+    def __init__(self, name, scriptFile=None, plugInSettings=[]):
+        """ Initialises a plug-in.
+        @details The supplied plug-in setting must be a key-value pair
+        co-responding to the plug-in option name and it's value respectively.
 
-		@param[in] name				The name of the plug-in.
-		@param[in] scriptFile		The path and file name of the script which
-									runs the plug-in.
-		@param[in] plugInSettings	A list of settings for the plug-in.
+        @param[in] name                The name of the plug-in.
+        @param[in] scriptFile        The path and file name of the script which
+                                    runs the plug-in.
+        @param[in] plugInSettings    A list of settings for the plug-in.
 
-		@post The object is ready for use.
-		"""
-		import os
+        @post The object is ready for use.
+        """
+        import os
 
-		self.__name = name
-		if (scriptFile is not None and len(scriptFile) > 0):
-			if os.path.exists(scriptFile):
-				self.__scriptFile = scriptFile
-			else:
-				raise ValueError("The plug-in file '%s' was not found." % scriptFile)
+        self.__name = name
+        if (scriptFile is not None and len(scriptFile) > 0):
+            if os.path.exists(scriptFile):
+                self.__scriptFile = scriptFile
+            else:
+                raise ValueError("The plug-in file '%s' was not found." %
+                                 scriptFile)
 
-		self.__settings = []
-		for plugInSetting in plugInSettings:
-			self.__settings.append(RepositoryPlugin.PluginSetting(plugInSetting[0], plugInSetting[1]))
+        self.__settings = []
+        for plugInSetting in plugInSettings:
+            self.__settings.append(RepositoryPlugin.PluginSetting(
+                plugInSetting[0], plugInSetting[1]))
 
-	def __eq__(self, other):
-		""" Determines if two repository plug-ins are the same.
+    def __eq__(self, other):
+        """ Determines if two repository plug-ins are the same.
 
-		@param[in] other	The plug-in on the right-hand-side of the
-							equality operator to compare against.
+        @param[in] other    The plug-in on the right-hand-side of the
+                            equality operator to compare against.
 
-		@return Gives true when both plug-ins represent the same one,
-		else-wise gives false.
-		"""
-		return self.name == other.name
+        @return Gives true when both plug-ins represent the same one,
+        else-wise gives false.
+        """
+        return self.name == other.name
 
-	def __str__(self):
-		""" Converts the object contents into a human-friendly string. """
-		plugIn = ""
-		if self.scriptFile is None:
-			plugIn = plugIn + self.name
-		else:
-			plugIn = plugIn + "%s -> %s" % (self.name, self.scriptFile)
-		for setting in self.settings:
-			plugIn = plugIn + "\n\t%s" % setting
-		return plugIn
+    def __str__(self):
+        """ Converts the object contents into a human-friendly string. """
+        plugIn = ""
+        if self.scriptFile is None:
+            plugIn = plugIn + self.name
+        else:
+            plugIn = plugIn + "%s -> %s" % (self.name, self.scriptFile)
+        for setting in self.settings:
+            plugIn = plugIn + "\n\t%s" % setting
+        return plugIn
 
-	def setPlugInSetting(self, name, value):
-		""" Set's the plug-in setting.
-		@details When the plug-in setting already exists the supplied value
-		overwrites the existing one. When the setting does not exist, a new
-		entry is created. When the supplied value is None, the setting is
-		removed from the plug-in.
+    def setPlugInSetting(self, name, value):
+        """ Set's the plug-in setting.
+        @details When the plug-in setting already exists the supplied value
+        overwrites the existing one. When the setting does not exist, a new
+        entry is created. When the supplied value is None, the setting is
+        removed from the plug-in.
 
-		@param[in] name				The name of the setting being set.
-		@param[in] value			The value for the setting.
+        @param[in] name                The name of the setting being set.
+        @param[in] value            The value for the setting.
 
-		@post The setting for the plug-in is modified to the supplied value.
-		"""
-		for setting in self.settings:
-			if name == setting.name:
-				if value is None:
-					self.__settings.remove(setting)
-				else:
-					settingIndex = self.settings.index(setting)
-					self.__settings[settingIndex].value = value
-				return
-		self.__settings.append(RepositoryPlugin.PluginSetting(name, value))
+        @post The setting for the plug-in is modified to the supplied value.
+        """
+        for setting in self.settings:
+            if name == setting.name:
+                if value is None:
+                    self.__settings.remove(setting)
+                else:
+                    settingIndex = self.settings.index(setting)
+                    self.__settings[settingIndex].value = value
+                return
+        self.__settings.append(RepositoryPlugin.PluginSetting(name, value))
 
 
 class ManagedCollection(object):
-	""" A container of all the managed repositories. """
+    """ A container of all the managed repositories. """
 
-	# All the managed repositories
-	__repositories = []
+    # All the managed repositories
+    __repositories = []
 
-	@property
-	def Repositories(self):
-		"""A collection of all managed repositories.
+    @property
+    def Repositories(self):
+        """A collection of all managed repositories.
 
-		@return An array of the managed repositories.
-		"""
-		return self.__repositories
+        @return An array of the managed repositories.
+        """
+        return self.__repositories
 
-	def __init__(self):
-		""" Initialises the container with all the managed repositories.
+    def __init__(self):
+        """ Initialises the container with all the managed repositories.
 
-		@throws RuntimeError	When the HgWeb configuration cannot be read.
-		"""
-		from ConfigParser import SafeConfigParser
-		import os
+        @throws RuntimeError    When the HgWeb configuration cannot be read.
+        """
+        from ConfigParser import SafeConfigParser
+        import os
 
-		parser = SafeConfigParser()
-		if not parser.read(settings.HgWebPath + os.sep + 'hgweb.config'):
-			raise RuntimeError("Failed to read HgWeb configuration.")
+        parser = SafeConfigParser()
+        if not parser.read(settings.HgWebPath + os.sep + 'hgweb.config'):
+            raise RuntimeError("Failed to read HgWeb configuration.")
 
-		for name, path in parser.items('paths'):
-			self.__repositories.append(Repository(name))
+        for name, path in parser.items('paths'):
+            self.__repositories.append(Repository(name))
 
-	def __str__(self):
-		""" Converts the object contents into a human-friendly string. """
-		collection = ""
-		for repository in self.Repositories:
-			collection = collection + str(repository) + '\n'
-		collection.rstrip('\n')
-		return collection
+    def __str__(self):
+        """ Converts the object contents into a human-friendly string. """
+        collection = ""
+        for repository in self.Repositories:
+            collection = collection + str(repository) + '\n'
+        collection.rstrip('\n')
+        return collection
--- a/src/manrepolock.py	Tue Apr 07 20:03:21 2015 +0200
+++ b/src/manrepolock.py	Fri Feb 19 18:45:37 2016 +0100
@@ -1,23 +1,24 @@
 # -*- coding: utf-8 -*-
-'''*****************************************************************************
-***  This file is part of HgWeb Manager.                                     ***
-***                                                                          ***
-***  Copyright (C) 2014 - 2015                                               ***
-***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                    ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Affero General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Affero General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Affero General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*****************************************************************************'''
+'''****************************************************************************
+***  This file is part of HgWeb Manager.                                    ***
+***                                                                         ***
+***  Copyright (C) 2014 - 2016                                              ***
+***  CodeGNU Solutions <Licensing _AT_ CodeGNU _DOT_ com>                   ***
+***                                                                         ***
+***  This program is free software: you can redistribute it and/or modify   ***
+***  it under the terms of the GNU Affero General Public License as         ***
+***  published by the Free Software Foundation, either version 3 of the     ***
+***  License, or (at your option) any later version.                        ***
+***                                                                         ***
+***  This program is distributed in the hope that it will be useful, but    ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of             ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                   ***
+***  See the GNU Affero General Public License for more details.            ***
+***                                                                         ***
+***  You should have received a copy of the GNU Affero General Public       ***
+***  License along with this program. If not,                               ***
+***  see <http://www.gnu.org/licenses/>.                                    ***
+****************************************************************************'''
 
 import errno
 import os
@@ -29,60 +30,61 @@
 
 
 class RepositoryManagerLock(object):
-	""" Handles the locking for the repository manager. """
+    """ Handles the locking for the repository manager. """
 
-	def __init__(self):
-		""" Initialises the lock for use, but does not get one. """
-		self.haveLock = False
+    def __init__(self):
+        """ Initialises the lock for use, but does not get one. """
+        self.haveLock = False
 
-	def __isLockedProcessRunning(self):
-		""" Determines if a process is already running
+    def __isLockedProcessRunning(self):
+        """ Determines if a process is already running
 
-		@return When the process is running gives true, false else-wise.
-		"""
-		try:
-			with open(repositoryLockFile) as previousLock:
-				pid = int(previousLock.readline())
-			os.kill(pid, 0)
-			return True
-		except OSError:
-			return False  # Process is not running.
+        @return When the process is running gives true, false else-wise.
+        """
+        try:
+            with open(repositoryLockFile) as previousLock:
+                pid = int(previousLock.readline())
+            os.kill(pid, 0)
+            return True
+        except OSError:
+            return False  # Process is not running.
 
-	def acquire(self):
-		""" Gets the repository lock. """
-		while True:
-			try:
-				print 'Acquiring repository manager lock ...'
-				self.lock = os.open(repositoryLockFile, os.O_CREAT | os.O_EXCL | os.O_RDWR)
-				break
-			except OSError as e:
-				if e.errno != errno.EEXIST:
-					raise
+    def acquire(self):
+        """ Gets the repository lock. """
+        while True:
+            try:
+                print 'Acquiring repository manager lock ...'
+                self.lock = os.open(repositoryLockFile, os.O_CREAT |
+                                    os.O_EXCL | os.O_RDWR)
+                break
+            except OSError as e:
+                if e.errno != errno.EEXIST:
+                    raise
 
-				if not self.__isLockedProcessRunning():
-					print 'A dead repository lock found, removing ...'
-					os.unlink(repositoryLockFile)
-				time.sleep(0.75)
-		self.haveLock = True
-		os.write(self.lock, str(os.getpid()))
+                if not self.__isLockedProcessRunning():
+                    print 'A dead repository lock found, removing ...'
+                    os.unlink(repositoryLockFile)
+                time.sleep(0.75)
+        self.haveLock = True
+        os.write(self.lock, str(os.getpid()))
 
-	def release(self):
-		""" Frees the repository lock. """
-		if self.haveLock:
-			print 'Releasing repository manager lock ...'
-			os.close(self.lock)
-			os.unlink(repositoryLockFile)
-			self.haveLock = False
+    def release(self):
+        """ Frees the repository lock. """
+        if self.haveLock:
+            print 'Releasing repository manager lock ...'
+            os.close(self.lock)
+            os.unlink(repositoryLockFile)
+            self.haveLock = False
 
-	def __enter__(self):
-		if not self.haveLock:
-			self.acquire()
-		return self
+    def __enter__(self):
+        if not self.haveLock:
+            self.acquire()
+        return self
 
-	def __exit__(self, type, value, traceback):
-		if self.haveLock:
-			self.release()
+    def __exit__(self, type, value, traceback):
+        if self.haveLock:
+            self.release()
 
-	def __del__(self):
-		""" Ensures that when the object is gone, the lock is released. """
-		self.release()
+    def __del__(self):
+        """ Ensures that when the object is gone, the lock is released. """
+        self.release()