# Path: module/plugins/internal/misc.py
# class Expose(object):
#     """
#     Used for decoration to declare rpc services
#     """
#     def __new__(cls, fn, *args, **kwargs):
#         hookManager.addRPC(fn.__module__, fn.__name__, fn.__doc__)
#         return fn
# 
# def encode(value, encoding='utf-8', errors='backslashreplace'):
#     """
#     Unicode string -> encoded string (default to UTF-8)
#     """
#     if isinstance(value, unicode):
#         res = value.encode(encoding, errors)
# 
#     elif isinstance(value, str):
#         decoding = get_console_encoding(sys.stdin.encoding)
#         if encoding == decoding:
#             res = value
#         else:
#             res = transcode(value, decoding, encoding)
# 
#     else:
#         res = str(value)
# 
#     return res
# 
# def exists(path):
#     path = encode(path)
# 
#     if os.path.exists(path):
#         if os.name == "nt":
#             dir, name = os.path.split(path.rstrip(os.sep))
#             return name.upper() in map(str.upper, os.listdir(dir))
#         else:
#             return True
#     else:
#         return False
# 
# def fsjoin(*args):
#     """
#     Like os.path.join, but encoding aware
#     (for safe-joining see `safejoin`)
#     """
#     return encode(os.path.join(*args))
# 
# def threaded(fn):
#     def run(*args, **kwargs):
#         hookManager.startThread(fn, *args, **kwargs)
# 
#     return run


import operator
import os
import re
import sys
import time
from ..internal.Addon import Addon
from ..internal.misc import Expose, encode, exists, fsjoin, threaded
                    (plugin_type.rstrip('s').upper(),
                     plugin_name),
                    e)  # @TODO: Remove rstrip in 0.4.10

        return updated

    #: Deprecated method, use `remove_plugins` instead
    @Expose
    def removePlugins(self, *args, **kwargs):
        """
        See `remove_plugins`
        """
        return self.remove_plugins(*args, **kwargs)

    @Expose
    def remove_plugins(self, plugin_ids):
        """
        Delete plugins from disk
        """
        if not plugin_ids:
            return

        removed = set()

        self.log_debug("Requested deletion of plugins: %s" % plugin_ids)

        for plugin_type, plugin_name in plugin_ids:
            rootplugins = os.path.join(pypath, "module", "plugins")

            for basedir in ("userplugins", rootplugins):

# Path: module/plugins/internal/misc.py
# class Expose(object):
#     """
#     Used for decoration to declare rpc services
#     """
#     def __new__(cls, fn, *args, **kwargs):
#         hookManager.addRPC(fn.__module__, fn.__name__, fn.__doc__)
#         return fn
# 
# def encode(value, encoding='utf-8', errors='backslashreplace'):
#     """
#     Unicode string -> encoded string (default to UTF-8)
#     """
#     if isinstance(value, unicode):
#         res = value.encode(encoding, errors)
# 
#     elif isinstance(value, str):
#         decoding = get_console_encoding(sys.stdin.encoding)
#         if encoding == decoding:
#             res = value
#         else:
#             res = transcode(value, decoding, encoding)
# 
#     else:
#         res = str(value)
# 
#     return res
# 
# def exists(path):
#     path = encode(path)
# 
#     if os.path.exists(path):
#         if os.name == "nt":
#             dir, name = os.path.split(path.rstrip(os.sep))
#             return name.upper() in map(str.upper, os.listdir(dir))
#         else:
#             return True
#     else:
#         return False
# 
# def fsjoin(*args):
#     """
#     Like os.path.join, but encoding aware
#     (for safe-joining see `safejoin`)
#     """
#     return encode(os.path.join(*args))
# 
# def threaded(fn):
#     def run(*args, **kwargs):
#         hookManager.startThread(fn, *args, **kwargs)
# 
#     return run


# Path: module/plugins/hooks/UpdateManager.py
import operator
import os
import re
import sys
import time
from ..internal.Addon import Addon
from ..internal.misc import Expose, encode, exists, fsjoin, threaded

                    (plugin_type.rstrip('s').upper(),
                     plugin_name),
                    e)  # @TODO: Remove rstrip in 0.4.10

        return updated

    #: Deprecated method, use `remove_plugins` instead
    @Expose
    def removePlugins(self, *args, **kwargs):
        """
        See `remove_plugins`
        """
        return self.remove_plugins(*args, **kwargs)

    @Expose
    def remove_plugins(self, plugin_ids):
        """
        Delete plugins from disk
        """
        if not plugin_ids:
            return

        removed = set()

        self.log_debug("Requested deletion of plugins: %s" % plugin_ids)

        for plugin_type, plugin_name in plugin_ids:
            rootplugins = os.path.join(pypath, "module", "plugins")

            for basedir in ("userplugins", rootplugins):

                py_filename = fsjoin(basedir, plugin_type, plugin_name + ".py")