<commit_before># Copyright (c) 2013, <NAME> <<EMAIL>>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA

import os
import site
import sys
import traceback
import urlparse

import rapport.config
import rapport.util


class Plugin(object):
    def __init__(self, alias=None, url=None, login=None, password=None):
        self.alias = alias
        self.url = url
        self.login = login
        self.password = password

        if alias == "":
            self.alias == self.__str__()

        if url and type(url) is not urlparse.ParseResult:
            self.url = urlparse.urlparse(url)

    def _results(self, dict={}):
        """Helper to merge a dict with cross-plugin defaults.

        All plugin sub-classes share some config values, i.e.  alias, url,
        login and password. This help should be used in the :collect: method
        of any Plugin implementation.

           >>> import rapport.plugin
           >>> c = rapport.plugin.Plugin(alias="a", url="http://example.com", login="u")
           >>> c._results()
           {'url': 'http://example.com', 'alias': 'a', 'login': 'u'}
           >>> c._results({'mykey': 'mykey'})
           {'url': 'http://example.com', 'alias': 'a', 'login': 'u', 'mykey': 'mykey'}
        """
        results = {"plugin": str(self),
                   "alias": self.alias,
                   "url": self.url,
                   "login": self.login}
        results.update(dict)
        return results

    def __str__(self):
        """Returns the class name in underscores.

        Additionally, for sub-classes, the suffix '_plugin' is split off.

            >>> import rapport.plugin
            >>> c = rapport.plugin.Plugin()
            >>> str(c)
            'plugin'
        """
        return rapport.util.camelcase_to_underscores(self.__class__.__name__).rsplit("_plugin")[0]

    def collect(self, timeframe):
        raise NotImplementedError()


def _get_plugin_dirs():
    """Return a list of directories where plugins may be located.
    """
    plugin_dirs = [
        os.path.expanduser(os.path.join("~", ".rapport", "plugins")),<commit_msg>Fix rapport.plugin doctests<commit_after># Copyright (c) 2013, <NAME> <<EMAIL>>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA

import os
import site
import sys
import traceback
import urlparse

import rapport.config
import rapport.util


class Plugin(object):
    def __init__(self, alias=None, url=None, login=None, password=<PASSWORD>):
        self.alias = alias
        self.url = url
        self.login = login
        self.password = password

        if alias == "":
            self.alias == self.__str__()

        if url and type(url) is not urlparse.ParseResult:
            self.url = urlparse.urlparse(url)

    def _results(self, dict={}):
        """Helper to merge a dict with cross-plugin defaults.

        All plugin sub-classes share some config values, i.e.  alias, url,
        login and password. This help should be used in the :collect: method
        of any Plugin implementation.

           >>> import rapport.plugin
           >>> c = rapport.plugin.Plugin(alias="a", url="http://example.com", login="u")
           >>> c._results()
           {'url': ParseResult(scheme='http', netloc='example.com', path='', params='', query='', fragment=''), 'alias': 'a', 'login': 'u', 'plugin': 'plugin'}
           >>> c._results({'mykey': 'mykey'})
           {'url': ParseResult(scheme='http', netloc='example.com', path='', params='', query='', fragment=''), 'alias': 'a', 'login': 'u', 'mykey': 'mykey', 'plugin': 'plugin'}
        """
        results = {"plugin": str(self),
                   "alias": self.alias,
                   "url": self.url,
                   "login": self.login}
        results.update(dict)
        return results

    def __str__(self):
        """Returns the class name in underscores.

        Additionally, for sub-classes, the suffix '_plugin' is split off.

            >>> import rapport.plugin
            >>> c = rapport.plugin.Plugin()
            >>> str(c)
            'plugin'
        """
        return rapport.util.camelcase_to_underscores(self.__class__.__name__).rsplit("_plugin")[0]

    def collect(self, timeframe):
        raise NotImplementedError()


def _get_plugin_dirs():
    """Return a list of directories where plugins may be located.
    """
    plugin_dirs = [
        os.path.expanduser(os.path.join("~", ".rapport", "plugins")),
{'fraction_non_alphanumeric': 0.12407342040240028, 'fraction_numerical': 0.006000705965407695, 'mean_word_length': 2.6561290322580646, 'pattern_counts': {'":': 10, '<': 10, '<?xml version=': 0, '>': 52, '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': '3259188', 'n_tokens_mistral': 1596, 'n_tokens_neox': 1528, 'n_words': 561}