<commit_before># -*- coding: utf-8 -*-

"""
    This program 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.

    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; if not, see <http://www.gnu.org/licenses/>.
    
    @author: mkaay, RaNaN
"""

import re
import sys

from os import listdir, makedirs
from os.path import isfile, join, exists, abspath
from sys import version_info
from itertools import chain
from traceback import print_exc

from module.lib.SafeEval import const_eval as literal_eval
from module.ConfigParser import IGNORE

class PluginManager:
    ROOT = "module.plugins."
    USERROOT = "userplugins."
    TYPES = ("crypter", "container", "hoster", "captcha", "accounts", "hooks", "internal")

    PATTERN = re.compile(r'__pattern__.*=.*r("|\')([^"\']+)')
    VERSION = re.compile(r'__version__.*=.*("|\')([0-9.]+)')
    CONFIG = re.compile(r'__config__.*=.*\[([^\]]+)', re.MULTILINE)
    DESC = re.compile(r'__description__.?=.?("|"""|\')([^"\']+)')


    def __init__(self, core):
        self.core = core

        #self.config = self.core.config
        self.log = core.log

        self.createIndex()

        self.plugins = {"crypter": self.crypterPlugins,
                        "container": self.containerPlugins,
                        "hoster": self.hosterPlugins,
                        "captcha": self.captchaPlugins,
                        "accounts": self.accountPlugins,
                        "hooks": self.hookPlugins,
                        "internal": self.internalPlugins}

        #register for import hook
        sys.meta_path.append(self)


    def createIndex(self):
        """create information for all plugins available"""

        sys.path.append(abspath(""))

        if not exists("userplugins"):
            makedirs("userplugins")
        if not exists(join("userplugins", "__init__.py")):
            f = open(join("userplugins", "__init__.py"), "wb")
            f.close()

        self.crypterPlugins = self.parse("crypter", pattern=True)
        self.containerPlugins = self.parse("container", pattern=True)
        self.hosterPlugins = self.parse("hoster", pattern=True)

        self.captchaPlugins = self.parse("captcha")
        self.accountPlugins = self.parse("accounts")
        self.hookPlugins = self.parse("hooks")
        self.internalPlugins = self.parse("internal")

        self.log.debug("created index of plugins")

    def parse(self, folder, pattern=False, home={}):
        """
        returns dict with information 
        home contains parsed plugins from module.
        
        {
        name : {path, version, config, (pattern, re), (plugin, class)}
        }
        
        """
        plugins = {}
        if home:
            pfolder = join("userplugins", folder)
            if not exists(pfolder):
                makedirs(pfolder)
            if not exists(join(pfolder, "__init__.py")):
                f = open(join(pfolder, "__init__.py"), "wb")
                f.close()

        else:
            pfolder = join(pypath, "module", "plugins", folder)

        for f in listdir(pfolder):
            if (isfile(join(pfolder, f)) and f.endswith(".py") or f.endswith("_25.pyc") or f.endswith(
                "_26.pyc") or f.endswith("_27.pyc")) and not f.startswith("_"):
                data = open(join(pfolder, f))
                content = data.read()
                data.close()

                if f.endswith("_25.pyc") and version_info[0:2] != (2, 5):
                    continue
                elif f.endswith("_26.pyc") and version_info[0:2] != (2, 6):
                    continue
                elif f.endswith("_27.pyc") and version_info[0:2] != (2, 7):
                    continue

                name = f[:-3]
                if name[-1] == ".": name = name[:-4]

                version = self.VERSION.findall(content)
                if version:
                    version = float(version[0][1])
                else:
                    version = 0

                # home contains plugins from pyload root
                if home and name in home:
                    if home[name]["v"] >= version:
                        continue

                plugins[name] = {}
                plugins[name]["v"] = version

                module = f.replace(".pyc", "").replace(".py", "")
                if home:
                    user = True
                else:
                    user = False

                    if name in IGNORE or (folder, name) in IGNORE:
                         del plugins[name]
                         continue

                # the plugin is loaded from user directory
                plugins[name]["user"] = user
                plugins[name]["name"] = module

                if pattern:
                    pattern = self.PATTERN.findall(content)

                    if pattern:
                        pattern = pattern[0][1]
                    else:
                        pattern = "^unmachtable$"

                    plugins[name]["pattern"] = pattern

                    try:
                        plugins[name]["re"] = re.compile(pattern)
                    except:
                        self.log.error(_("%s has a invalid pattern.") % name)


                # internals have no config
                if folder == "internal":
                    self.core.config.deleteConfig(name)
                    continue

                config = self.CONFIG.findall(content)<commit_msg>little fix<commit_after># -*- coding: utf-8 -*-

"""
    This program 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.

    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; if not, see <http://www.gnu.org/licenses/>.
    
    @author: mkaay, RaNaN
"""

import re
import sys

from os import listdir, makedirs
from os.path import isfile, join, exists, abspath
from sys import version_info
from itertools import chain
from traceback import print_exc

from module.lib.SafeEval import const_eval as literal_eval
from module.ConfigParser import IGNORE

class PluginManager:
    ROOT = "module.plugins."
    USERROOT = "userplugins."
    TYPES = ("crypter", "container", "hoster", "captcha", "accounts", "hooks", "internal")

    PATTERN = re.compile(r'__pattern__.*=.*r("|\')([^"\']+)')
    VERSION = re.compile(r'__version__.*=.*("|\')([0-9.]+)')
    CONFIG = re.compile(r'__config__.*=.*\[([^\]]+)', re.MULTILINE)
    DESC = re.compile(r'__description__.?=.?("|"""|\')([^"\']+)')


    def __init__(self, core):
        self.core = core

        #self.config = self.core.config
        self.log = core.log

        self.createIndex()

        self.plugins = {"crypter": self.crypterPlugins,
                        "container": self.containerPlugins,
                        "hoster": self.hosterPlugins,
                        "captcha": self.captchaPlugins,
                        "accounts": self.accountPlugins,
                        "hooks": self.hookPlugins,
                        "internal": self.internalPlugins}

        #register for import hook
        sys.meta_path.append(self)


    def createIndex(self):
        """create information for all plugins available"""

        sys.path.append(abspath(""))

        if not exists("userplugins"):
            makedirs("userplugins")
        if not exists(join("userplugins", "__init__.py")):
            f = open(join("userplugins", "__init__.py"), "wb")
            f.close()

        self.crypterPlugins = self.parse("crypter", pattern=True)
        self.containerPlugins = self.parse("container", pattern=True)
        self.hosterPlugins = self.parse("hoster", pattern=True)

        self.captchaPlugins = self.parse("captcha")
        self.accountPlugins = self.parse("accounts")
        self.hookPlugins = self.parse("hooks")
        self.internalPlugins = self.parse("internal")

        self.log.debug("created index of plugins")

    def parse(self, folder, pattern=False, home={}):
        """
        returns dict with information 
        home contains parsed plugins from module.
        
        {
        name : {path, version, config, (pattern, re), (plugin, class)}
        }
        
        """
        plugins = {}
        if home:
            pfolder = join("userplugins", folder)
            if not exists(pfolder):
                makedirs(pfolder)
            if not exists(join(pfolder, "__init__.py")):
                f = open(join(pfolder, "__init__.py"), "wb")
                f.close()

        else:
            pfolder = join(pypath, "module", "plugins", folder)

        for f in listdir(pfolder):
            if (isfile(join(pfolder, f)) and f.endswith(".py") or f.endswith("_25.pyc") or f.endswith(
                "_26.pyc") or f.endswith("_27.pyc")) and not f.startswith("_"):
                data = open(join(pfolder, f))
                content = data.read()
                data.close()

                if f.endswith("_25.pyc") and version_info[0:2] != (2, 5):
                    continue
                elif f.endswith("_26.pyc") and version_info[0:2] != (2, 6):
                    continue
                elif f.endswith("_27.pyc") and version_info[0:2] != (2, 7):
                    continue

                name = f[:-3]
                if name[-1] == ".": name = name[:-4]

                version = self.VERSION.findall(content)
                if version:
                    version = float(version[0][1])
                else:
                    version = 0

                # home contains plugins from pyload root
                if home and name in home:
                    if home[name]["v"] >= version:
                        continue

                if name in IGNORE or (folder, name) in IGNORE:
                     continue

                plugins[name] = {}
                plugins[name]["v"] = version

                module = f.replace(".pyc", "").replace(".py", "")

                # the plugin is loaded from user directory
                plugins[name]["user"] = True if home else False
                plugins[name]["name"] = module

                if pattern:
                    pattern = self.PATTERN.findall(content)

                    if pattern:
                        pattern = pattern[0][1]
                    else:
                        pattern = "^unmachtable$"

                    plugins[name]["pattern"] = pattern

                    try:
                        plugins[name]["re"] = re.compile(pattern)
                    except:
                        self.log.error(_("%s has a invalid pattern.") % name)


                # internals have no config
                if folder == "internal":
                    self.core.config.deleteConfig(name)
                    continue

                config = self.CONFIG.findall(content)
{'fraction_non_alphanumeric': 0.12037906599504823, 'fraction_numerical': 0.006147016135917357, 'mean_word_length': 1.6990783410138248, 'pattern_counts': {'":': 18, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '2207311', 'n_tokens_mistral': 3338, 'n_tokens_neox': 3094, 'n_words': 863}