<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function
import os
import logging
import collections
import re
import util
import subprocess
import types
import osutil
import shutil


__author__ = 'dusanklinec'
logger = logging.getLogger(__name__)


CONFIG_LINE_BLANK = 0
CONFIG_LINE_COMMENT = 1
CONFIG_LINE_CMD_COMMENT = 2
CONFIG_LINE_CMD = 3


class ConfigLine(object):
    """
    # One open vpn config line
    """
    def __init__(self, idx=None, raw=None, ltype=None, cmd=None, params=None, comment=None, *args, **kwargs):
        self.idx = idx
        self._raw = raw
        self.ltype = ltype
        self.cmd = cmd
        self.params = params if params is not None else ''
        self.comment = comment if comment is not None else ''

    @property
    def raw(self):
        """
        Builds raw config line
        :return:
        """
        if self.ltype in [CONFIG_LINE_COMMENT, CONFIG_LINE_BLANK]:
            return self._raw

        res = '' if self.ltype == CONFIG_LINE_CMD else ';'
        res += '%s %s %s' % (self.cmd, self.params, self.comment)
        return res

    @raw.setter
    def raw(self, val):
        self._raw = val

    @classmethod
    def build(cls, line, idx=0):
        line = line.strip()
        cl = cls(idx=idx, raw=line)

        if line is None or len(line.strip()) == 0:
            cl.ltype = CONFIG_LINE_BLANK
            return cl

        cmt_match = re.match(r'^\s*#.*', line)
        if cmt_match is not None:
            cl.ltype = CONFIG_LINE_COMMENT
            return cl

        cmd_cmt_match = re.match(r'^\s*;.*', line)
        cmd_match = re.match(r'^\s*(;)?\s*([a-zA-Z0-9\-_]+)\s+(.+?)(\s*(#|;).+)?$', line)

        if cmd_match is None and cmd_cmt_match is not None:
            cl.ltype = CONFIG_LINE_COMMENT
            return cl

        cl.ltype = CONFIG_LINE_CMD if cmd_match.group(1) is None else CONFIG_LINE_CMD_COMMENT
        cl.cmd = cmd_match.group(2).strip()
        cl.params = cmd_match.group(3).strip()
        cl.comment = cmd_match.group(4)
        return cl


class OpenVpn(object):
    """
    OpenVPN server configuration & management
    """

    SETTINGS_DIR = '/etc/openvpn'
    SETTINGS_FILE = 'server.conf'

    def __init__(self, sysconfig=None, *args, **kwargs):
        self.sysconfig = sysconfig

        # Result of load_config_file_lines
        self.server_config_data = None
        self.server_config_modified = False

    #
    # server.conf reading & modification
    #
    def get_config_dir(self):
        return self.SETTINGS_DIR

    def get_config_dir_subfile(self, filename):
        return os.path.join(self.get_config_dir(), filename)

    def get_config_file_path(self):
        """
        Returns config file path
        :return: server config file path
        """
        return os.path.join(self.SETTINGS_DIR, self.SETTINGS_FILE)

    def load_config_file_lines(self):
        """
        Loads config file to a string
        :return: array of ConfigLine or None if file does not exist
        """
        cpath = self.get_config_file_path()
        if not os.path.exists(cpath):
            return []

        lines = []
        with open(cpath, 'r') as fh:
            for idx, line in enumerate(fh):
                ln = ConfigLine.build(line=line, idx=idx)
                lines.append(ln)
        return lines

    def set_config_value(self, cmd, values, remove=False):
        """
        Sets command to the specified value in the configuration file.
        Loads file from the disk if server_config_data is None (file was not yet loaded).

        Supports also multicommands - one command with more values.

        Modifies self.server_config_data, self.server_config_modified
        :param cmd:
        :param values: single value or array of values for multi-commands (e.g., push).
                       None & remove -> remove all commands. Otherwise just commands with the given values are removed.
        :param remove: if True, configuration command is removed
        :return: True if file was modified
        """
        # If file is not loaded - load
        if self.server_config_data is None:
            self.server_config_data = self.load_config_file_lines()

        last_cmd_idx = 0
        file_changed = False
        if not isinstance(values, types.ListType):
            if values is None:
                values = []
            else:
                values = [values]

        values_set = [False] * len(values)
        for idx, cfg in enumerate(self.server_config_data):
            if cfg.ltype not in [CONFIG_LINE_CMD, CONFIG_LINE_CMD_COMMENT]:
                continue
            if cfg.cmd != cmd:
                continue

            # Only commands of interest here
            last_cmd_idx = idx
            is_desired_value = cfg.params in values
            is_desired_value |= remove and len(values) == 0
            value_idx = values.index(cfg.params) if not remove and cfg.params in values else None<commit_msg>ovpn - commands appended if not found in the file<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function
import os
import logging
import collections
import re
import util
import subprocess
import types
import osutil
import shutil


__author__ = 'dusanklinec'
logger = logging.getLogger(__name__)


CONFIG_LINE_BLANK = 0
CONFIG_LINE_COMMENT = 1
CONFIG_LINE_CMD_COMMENT = 2
CONFIG_LINE_CMD = 3


class ConfigLine(object):
    """
    # One open vpn config line
    """
    def __init__(self, idx=None, raw=None, ltype=None, cmd=None, params=None, comment=None, *args, **kwargs):
        self.idx = idx
        self._raw = raw
        self.ltype = ltype
        self.cmd = cmd
        self.params = params if params is not None else ''
        self.comment = comment if comment is not None else ''

    @property
    def raw(self):
        """
        Builds raw config line
        :return:
        """
        if self.ltype in [CONFIG_LINE_COMMENT, CONFIG_LINE_BLANK]:
            return self._raw

        res = '' if self.ltype == CONFIG_LINE_CMD else ';'
        res += '%s %s %s' % (self.cmd, self.params, self.comment)
        return res

    @raw.setter
    def raw(self, val):
        self._raw = val

    @classmethod
    def build(cls, line, idx=0):
        line = line.strip()
        cl = cls(idx=idx, raw=line)

        if line is None or len(line.strip()) == 0:
            cl.ltype = CONFIG_LINE_BLANK
            return cl

        cmt_match = re.match(r'^\s*#.*', line)
        if cmt_match is not None:
            cl.ltype = CONFIG_LINE_COMMENT
            return cl

        cmd_cmt_match = re.match(r'^\s*;.*', line)
        cmd_match = re.match(r'^\s*(;)?\s*([a-zA-Z0-9\-_]+)\s+(.+?)(\s*(#|;).+)?$', line)

        if cmd_match is None and cmd_cmt_match is not None:
            cl.ltype = CONFIG_LINE_COMMENT
            return cl

        cl.ltype = CONFIG_LINE_CMD if cmd_match.group(1) is None else CONFIG_LINE_CMD_COMMENT
        cl.cmd = cmd_match.group(2).strip()
        cl.params = cmd_match.group(3).strip()
        cl.comment = cmd_match.group(4)
        return cl


class OpenVpn(object):
    """
    OpenVPN server configuration & management
    """

    SETTINGS_DIR = '/etc/openvpn'
    SETTINGS_FILE = 'server.conf'

    def __init__(self, sysconfig=None, *args, **kwargs):
        self.sysconfig = sysconfig

        # Result of load_config_file_lines
        self.server_config_data = None
        self.server_config_modified = False

    #
    # server.conf reading & modification
    #
    def get_config_dir(self):
        return self.SETTINGS_DIR

    def get_config_dir_subfile(self, filename):
        return os.path.join(self.get_config_dir(), filename)

    def get_config_file_path(self):
        """
        Returns config file path
        :return: server config file path
        """
        return os.path.join(self.SETTINGS_DIR, self.SETTINGS_FILE)

    def load_config_file_lines(self):
        """
        Loads config file to a string
        :return: array of ConfigLine or None if file does not exist
        """
        cpath = self.get_config_file_path()
        if not os.path.exists(cpath):
            return []

        lines = []
        with open(cpath, 'r') as fh:
            for idx, line in enumerate(fh):
                ln = ConfigLine.build(line=line, idx=idx)
                lines.append(ln)
        return lines

    def set_config_value(self, cmd, values, remove=False):
        """
        Sets command to the specified value in the configuration file.
        Loads file from the disk if server_config_data is None (file was not yet loaded).

        Supports also multicommands - one command with more values.

        Modifies self.server_config_data, self.server_config_modified
        :param cmd:
        :param values: single value or array of values for multi-commands (e.g., push).
                       None & remove -> remove all commands. Otherwise just commands with the given values are removed.
        :param remove: if True, configuration command is removed
        :return: True if file was modified
        """
        # If file is not loaded - load
        if self.server_config_data is None:
            self.server_config_data = self.load_config_file_lines()

        last_cmd_idx = len(self.server_config_data)
        file_changed = False
        if not isinstance(values, types.ListType):
            if values is None:
                values = []
            else:
                values = [values]

        values_set = [False] * len(values)
        for idx, cfg in enumerate(self.server_config_data):
            if cfg.ltype not in [CONFIG_LINE_CMD, CONFIG_LINE_CMD_COMMENT]:
                continue
            if cfg.cmd != cmd:
                continue

            # Only commands of interest here
            last_cmd_idx = idx
            is_desired_value = cfg.params in values
            is_desired_value |= remove and len(values) == 0
            value_idx = values.index(cfg.params) if not remove and cfg.params in values else None
{'fraction_non_alphanumeric': 0.09483354736738121, 'fraction_numerical': 0.0028647634100563073, 'mean_word_length': 2.1285537700865267, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4499839', 'n_tokens_mistral': 3060, 'n_tokens_neox': 2971, 'n_words': 869}