From 517c9e6b6972621581eeb0254b081223f840534a Mon Sep 17 00:00:00 2001
From: Florian Bruhin <git@the-compiler.org>
Date: Wed, 16 Apr 2014 16:16:17 +0200
Subject: [PATCH] Split config.py more

---
 qutebrowser/config/config.py     | 142 +++++--------------------------
 qutebrowser/config/iniparsers.py |  62 ++++++++++++++
 qutebrowser/config/lineparser.py |  90 ++++++++++++++++++++
 3 files changed, 171 insertions(+), 123 deletions(-)
 create mode 100644 qutebrowser/config/iniparsers.py
 create mode 100644 qutebrowser/config/lineparser.py

diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py
index 11a7ba1ec..df652654f 100644
--- a/qutebrowser/config/config.py
+++ b/qutebrowser/config/config.py
@@ -27,22 +27,39 @@ import os.path
 import logging
 import textwrap
 import configparser
-from configparser import ConfigParser, ExtendedInterpolation
+from configparser import ExtendedInterpolation
 from collections.abc import MutableMapping
 
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject
+from PyQt5.QtCore import pyqtSignal, QObject
 
 #from qutebrowser.utils.misc import read_file
 import qutebrowser.config.configdata as configdata
 import qutebrowser.commands.utils as cmdutils
 import qutebrowser.utils.message as message
 from qutebrowser.config.conftypes import ValidationError
+from qutebrowser.config.iniparsers import (ReadConfigParser,
+                                           ReadWriteConfigParser)
+from qutebrowser.config.lineparser import LineConfigParser
 
 config = None
 state = None
 cmd_history = None
 
 
+def init(configdir):
+    """Initialize the global objects based on the config in configdir.
+
+    Args:
+        configdir: The directory where the configs are stored in.
+    """
+    global config, state, cmd_history
+    logging.debug("Config init, configdir {}".format(configdir))
+    config = Config(configdir, 'qutebrowser.conf')
+    state = ReadWriteConfigParser(configdir, 'state')
+    cmd_history = LineConfigParser(configdir, 'cmd_history',
+                                   ('general', 'cmd_histlen'))
+
+
 class NoSectionError(configparser.NoSectionError):
 
     """Exception raised when a section was not found."""
@@ -57,22 +74,6 @@ class NoOptionError(configparser.NoOptionError):
     pass
 
 
-def init(configdir):
-    """Initialize the global objects based on the config in configdir.
-
-    Args:
-        configdir: The directory where the configs are stored in.
-    """
-    global config, state, cmd_history
-    logging.debug("Config init, configdir {}".format(configdir))
-    #config = Config(configdir, 'qutebrowser.conf',
-    #                read_file('qutebrowser.conf'))
-    config = Config(configdir, 'qutebrowser.conf')
-    state = ReadWriteConfigParser(configdir, 'state')
-    cmd_history = LineConfigParser(configdir, 'cmd_history',
-                                   ('general', 'cmd_histlen'))
-
-
 class Config(QObject):
 
     """Configuration manager for qutebrowser.
@@ -364,111 +365,6 @@ class Config(QObject):
         return val
 
 
-class ReadConfigParser(ConfigParser):
-
-    """Our own ConfigParser subclass to read the main config.
-
-    Attributes:
-        _configdir: The directory to read the config from.
-        _configfile: The config file path.
-    """
-
-    def __init__(self, configdir, fname):
-        """Config constructor.
-
-        Args:
-            configdir: Directory to read the config from.
-            fname: Filename of the config file.
-        """
-        super().__init__(interpolation=None)
-        self.optionxform = lambda opt: opt  # be case-insensitive
-        self._configdir = configdir
-        self._configfile = os.path.join(self._configdir, fname)
-        if not os.path.isfile(self._configfile):
-            return
-        logging.debug("Reading config from {}".format(self._configfile))
-        self.read(self._configfile)
-
-
-class ReadWriteConfigParser(ReadConfigParser):
-
-    """ConfigParser subclass used for auxillary config files."""
-
-    def save(self):
-        """Save the config file."""
-        if not os.path.exists(self._configdir):
-            os.makedirs(self._configdir, 0o755)
-        logging.debug("Saving config to {}".format(self._configfile))
-        with open(self._configfile, 'w') as f:
-            self.write(f)
-
-
-class LineConfigParser:
-
-    """Parser for configuration files which are simply line-based.
-
-    Attributes:
-        data: A list of lines.
-        _configdir: The directory to read the config from.
-        _configfile: The config file path.
-    """
-
-    def __init__(self, configdir, fname, limit=None):
-        """Config constructor.
-
-        Args:
-            configdir: Directory to read the config from.
-            fname: Filename of the config file.
-            limit: Config tuple (section, option) which contains a limit.
-        """
-        self._configdir = configdir
-        self._configfile = os.path.join(self._configdir, fname)
-        self._limit = limit
-        self.data = None
-        if not os.path.isfile(self._configfile):
-            return
-        logging.debug("Reading config from {}".format(self._configfile))
-        self.read(self._configfile)
-
-    def read(self, filename):
-        """Read the data from a file."""
-        with open(filename, 'r') as f:
-            self.data = [line.rstrip('\n') for line in f.readlines()]
-
-    def write(self, fp, limit=-1):
-        """Write the data to a file.
-
-        Arguments:
-            fp: A file object to write the data to.
-            limit: How many lines to write, or -1 for no limit.
-        """
-        if limit == -1:
-            data = self.data
-        else:
-            data = self.data[-limit:]
-        fp.write('\n'.join(data))
-
-    def save(self):
-        """Save the config file."""
-        limit = -1 if self._limit is None else config.get(*self._limit)
-        if limit == 0:
-            return
-        if not os.path.exists(self._configdir):
-            os.makedirs(self._configdir, 0o755)
-        logging.debug("Saving config to {}".format(self._configfile))
-        with open(self._configfile, 'w') as f:
-            self.write(f, limit)
-
-    @pyqtSlot(str, str, object)
-    def on_config_changed(self, section, option, value):
-        """Delete the file if the limit was changed to 0."""
-        if self._limit is None:
-            return
-        if (section, option) == self._limit and value == 0:
-            if os.path.exists(self._configfile):
-                os.remove(self._configfile)
-
-
 class SectionProxy(MutableMapping):
 
     """A proxy for a single section from a config.
diff --git a/qutebrowser/config/iniparsers.py b/qutebrowser/config/iniparsers.py
new file mode 100644
index 000000000..fbff6995b
--- /dev/null
+++ b/qutebrowser/config/iniparsers.py
@@ -0,0 +1,62 @@
+# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
+#
+# This file is part of qutebrowser.
+#
+# qutebrowser is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# qutebrowser 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with qutebrowser.  If not, see <http://www.gnu.org/licenses/>.
+
+"""Parsers for INI-like config files, based on Python's ConfigParser."""
+
+import os
+import os.path
+import logging
+from configparser import ConfigParser
+
+
+class ReadConfigParser(ConfigParser):
+
+    """Our own ConfigParser subclass to read the main config.
+
+    Attributes:
+        _configdir: The directory to read the config from.
+        _configfile: The config file path.
+    """
+
+    def __init__(self, configdir, fname):
+        """Config constructor.
+
+        Args:
+            configdir: Directory to read the config from.
+            fname: Filename of the config file.
+        """
+        super().__init__(interpolation=None)
+        self.optionxform = lambda opt: opt  # be case-insensitive
+        self._configdir = configdir
+        self._configfile = os.path.join(self._configdir, fname)
+        if not os.path.isfile(self._configfile):
+            return
+        logging.debug("Reading config from {}".format(self._configfile))
+        self.read(self._configfile)
+
+
+class ReadWriteConfigParser(ReadConfigParser):
+
+    """ConfigParser subclass used for auxillary config files."""
+
+    def save(self):
+        """Save the config file."""
+        if not os.path.exists(self._configdir):
+            os.makedirs(self._configdir, 0o755)
+        logging.debug("Saving config to {}".format(self._configfile))
+        with open(self._configfile, 'w') as f:
+            self.write(f)
diff --git a/qutebrowser/config/lineparser.py b/qutebrowser/config/lineparser.py
new file mode 100644
index 000000000..4b3004ef1
--- /dev/null
+++ b/qutebrowser/config/lineparser.py
@@ -0,0 +1,90 @@
+# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
+#
+# This file is part of qutebrowser.
+#
+# qutebrowser is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# qutebrowser 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with qutebrowser.  If not, see <http://www.gnu.org/licenses/>.
+
+"""Parser for line-based configurations like histories."""
+
+import os
+import os.path
+import logging
+from PyQt5.QtCore import pyqtSlot
+
+
+class LineConfigParser:
+
+    """Parser for configuration files which are simply line-based.
+
+    Attributes:
+        data: A list of lines.
+        _configdir: The directory to read the config from.
+        _configfile: The config file path.
+    """
+
+    def __init__(self, configdir, fname, limit=None):
+        """Config constructor.
+
+        Args:
+            configdir: Directory to read the config from.
+            fname: Filename of the config file.
+            limit: Config tuple (section, option) which contains a limit.
+        """
+        self._configdir = configdir
+        self._configfile = os.path.join(self._configdir, fname)
+        self._limit = limit
+        self.data = None
+        if not os.path.isfile(self._configfile):
+            return
+        logging.debug("Reading config from {}".format(self._configfile))
+        self.read(self._configfile)
+
+    def read(self, filename):
+        """Read the data from a file."""
+        with open(filename, 'r') as f:
+            self.data = [line.rstrip('\n') for line in f.readlines()]
+
+    def write(self, fp, limit=-1):
+        """Write the data to a file.
+
+        Arguments:
+            fp: A file object to write the data to.
+            limit: How many lines to write, or -1 for no limit.
+        """
+        if limit == -1:
+            data = self.data
+        else:
+            data = self.data[-limit:]
+        fp.write('\n'.join(data))
+
+    def save(self):
+        """Save the config file."""
+        from qutebrowser.config.config import config
+        limit = -1 if self._limit is None else config.config.get(*self._limit)
+        if limit == 0:
+            return
+        if not os.path.exists(self._configdir):
+            os.makedirs(self._configdir, 0o755)
+        logging.debug("Saving config to {}".format(self._configfile))
+        with open(self._configfile, 'w') as f:
+            self.write(f, limit)
+
+    @pyqtSlot(str, str, object)
+    def on_config_changed(self, section, option, value):
+        """Delete the file if the limit was changed to 0."""
+        if self._limit is None:
+            return
+        if (section, option) == self._limit and value == 0:
+            if os.path.exists(self._configfile):
+                os.remove(self._configfile)