예제 #1
0
def uninstall(plugin):
    """Uninstall a plugin"""
    profile = config.plugins.profile
    dest_dir = profile.pluginsdir

    def plugin_location(plugin):
        return os.path.join(dest_dir, "{}.py".format(plugin_file_name(plugin)))

    for _plugin in plugin:
        plugin_name = _plugin.replace('/', '_')
        from click_project.plugins import plugins
        plugin_mod = plugins.load_plugin(plugin_name)
        if hasattr(plugin_mod, "before_uninstall"):
            plugin_mod.before_uninstall()
        if not os.path.exists(plugin_location(_plugin)):
            LOGGER.warning("Plugin {} does not exist in profile {}.".format(
                _plugin,
                profile.name,
            ))
            continue
        LOGGER.status("Uninstalling plugin {} from profile {}".format(
            _plugin, profile.name))
        pl = plugin_location(_plugin)
        rm(pl)
        if os.path.exists(pl + 'c'):
            rm(pl + 'c')
예제 #2
0
def tesseract(input, language, remove_after):
    """Extract the text from a pdf and create a searchable pdf"""
    ocr_base = os.path.splitext(input)[0] + "_ocr"
    with temporary_file(suffix=".tiff") as tiff:
        call(split(f"convert -density 300 '{input}' -depth 8 '{tiff.name}'"))
        call(split(f"tesseract '{tiff.name}' '{ocr_base}' -l '{language}' pdf"))
    if remove_after:
        rm(input)
예제 #3
0
    def recipes_instead_of_settings_level(self):
        if self.isrecipe:
            return True
        recipes_dir = self.location + "/recipes/"

        def migrate_settings_to_recipe(settings_level_file, name):
            if open(settings_level_file,
                    "rb").read().decode("utf-8").strip() == "{}":
                return False
            makedirs(recipes_dir + "/" + name)
            enabled = not json.load(open(settings_level_file)).get(
                "_self", {}).get("disabled", False)
            order = json.load(open(settings_level_file)).get("_self", {}).get(
                "order", 100)
            move(settings_level_file,
                 recipes_dir + "/" + name + "/{}.json".format(self.app_name))
            createfile(recipes_dir + "/" + name + "/version.txt",
                       str(self.version + 1))
            createfile(recipes_dir + "/" + name + ".json",
                       json.dumps({
                           "enabled": enabled,
                           "order": order,
                       }))
            return True

        migrate_something = False
        for settings_level_file in glob(self.location +
                                        "/{}-*.json".format(self.app_name)):
            name = re.sub(".+{}-([a-zA-Z-]+).json$".format(self.app_name),
                          r"\1", settings_level_file)
            name = name.replace("-", "_")
            if name == "private":
                continue
            migrate_something |= migrate_settings_to_recipe(
                settings_level_file, name + "_from_settings")
        private = self.location + "/{}-private.json".format(self.app_name)
        local = self.location + "/{}.json".format(self.app_name)
        if os.path.exists(private):
            if open(private, "rb").read().decode("utf-8").strip() != "{}":
                migrate_something = True
            else:
                rm(private)
        if migrate_something is True:
            name = "migrated_local"
            if os.path.exists(local) and not open(
                    local, "rb").read().decode("utf-8").strip() == "{}":
                migrate_settings_to_recipe(local, name)
            if os.path.exists(private):
                move(private, local)
            with json_file(local) as values:
                recipes = values.get("recipe", {})
                local_order = recipes.get(name, {})
                local_order["order"] = 0
                recipes[name] = local_order
                values["recipe"] = recipes
            self.computed_location = None
            self.compute_settings()
        return True
예제 #4
0
def clean():
    """Remove the files/directories known by git from your file system

    It makes the file system bare naked, like before the first restore call.

    """
    for rel in config.git_record.readonly.keys():
        full = os.path.join(config.project, rel)
        if os.path.exists(full):
            LOGGER.status("Removing {}".format(rel))
            rm(full)
예제 #5
0
 def migrate(self, persist=True):
     LOGGER.action("migrate profile in {}".format(self.location))
     if self.dry_run:
         return False
     if os.path.exists(self.backup_location):
         LOGGER.error(
             "{} already exists. Cannot migrate.".format(self.backup_location)
         )
         return False
     makedirs(self.backup_location)
     for name in self.migration_impact:
         if os.path.exists(os.path.join(self.location, name)):
             copy(
                 os.path.join(self.location, name),
                 os.path.join(self.backup_location, name),
             )
     try:
         res = self._migrate(persist)
     except Exception as e:
         import traceback
         LOGGER.error(e)
         LOGGER.develop(traceback.format_exc())
         res = False
     if res:
         rm(self.backup_location)
     else:
         if persist:
             LOGGER.warning(
                 "The migration of {} did not go well,"
                 " Restoring backup from {}".format(
                     self.location,
                     self.backup_location
                 )
             )
         for name in self.migration_impact:
             if os.path.exists(os.path.join(self.backup_location, name)):
                 if os.path.exists(os.path.join(self.location, name)):
                     rm(
                         os.path.join(self.location, name)
                     )
                 copy(
                     os.path.join(self.backup_location, name),
                     os.path.join(self.location, name),
                 )
         rm(self.backup_location)
     return res
예제 #6
0
def install_plugin(profile, force, plugin, login, password, develop, no_deps):
    """Install a plugin"""
    dest_dir = profile.pluginsdir

    def plugin_location(plugin):
        return os.path.join(dest_dir, "{}.py".format(plugin_file_name(plugin)))

    for _plugin in plugin:
        if not force and os.path.exists(plugin_location(_plugin)):
            raise click.UsageError(
                "{} already installed in profile {}."
                " If you really want to install it, use --force or"
                " run plugin uninstall --{} {}".format(_plugin, profile.name,
                                                       profile.name, _plugin))
    for _plugin in plugin:
        if is_local_plugin(_plugin):
            if _plugin.startswith("file://"):
                content = open(_plugin[len("file://"):],
                               "rb").read().decode("utf-8")
                plugin_file = os.path.abspath(_plugin[len("file://"):])
            else:
                content = open(_plugin, "rb").read().decode("utf-8")
                plugin_file = os.path.abspath(_plugin)
            plugin_name = os.path.basename(plugin_file)[:-3]
            plugin_dir = os.path.dirname(plugin_file)
            if os.path.basename(plugin_dir) != "{}_plugins".format(
                    config.app_name):
                raise click.UsageError(
                    "{} does not look like a plugin directory".format(
                        plugin_dir))
            user_name = os.path.basename(os.path.dirname(plugin_dir))
            plugin_name = "{}/{}".format(user_name, plugin_name)
        else:
            content = get_plugin_from_remote(_plugin)
            plugin_name = _plugin

        def install_requirements():
            require_prefix = "# require: "
            requires = [
                line[len(require_prefix):] for line in content.splitlines()
                if line.startswith(require_prefix)
            ]
            for require in requires:
                LOGGER.status("Installing requirement {}".format(require))
                args = ['--upgrade', require]
                if force:
                    args.append("--force-reinstall")
                pip("install", args)
            plugin_require_prefix = "# plugin_require: "
            plugin_requires = [
                line[len(plugin_require_prefix):]
                for line in content.splitlines()
                if line.startswith(plugin_require_prefix)
            ]
            for plugin_require in plugin_requires:
                LOGGER.status(
                    "Installing plugin requirements {}".format(plugin_require))
                install_plugin(
                    profile=profile,
                    force=force,
                    login=login,
                    password=password,
                    plugin=[plugin_require],
                    develop=False,
                    no_deps=no_deps,
                )

        if not no_deps:
            install_requirements()
        LOGGER.status("Installing plugin {} in profile {}".format(
            plugin_name, profile.name))
        location = plugin_location(plugin_name)
        makedirs(os.path.dirname(location))

        if is_local_plugin(_plugin) and develop:
            LOGGER.debug("Installing {} in develop mode".format(plugin_name))
            if force and os.path.exists(location):
                rm(location)
            ln(plugin_file, location)
        else:
            createfile(location, content)
예제 #7
0
 def remove_recipe(self, name):
     r = self.get_recipe(name)
     rm(r.location)
예제 #8
0
def _unset(recipes):
    """Remove the the link file"""
    for recipe in recipes:
        rm(config.recipe.profile.link_location(recipe))
        LOGGER.status("Removing the link file of {} ({})".format(
            recipe, config.recipe.writeprofile))
예제 #9
0
def remove(force, customcommand):
    """Remove the given custom command"""
    path = Path(customcommand.customcommand_path)
    if force or click.confirm(f"This will remove {path}, are you sure ?"):
        rm(path)
예제 #10
0
def fork(force, name):
    """Create a brand new project, based on clk that can be used by itself."""
    output = Path(name)
    if output.exists():
        if force:
            rm(output)
        else:
            raise click.UsageError(f"{output} already exist")
    makedirs(output)
    createfile(
        output / "setup.py", f"""#!/usr/bin/env python3
# -*- coding:utf-8 -*-

from setuptools import setup, find_packages

setup(
    name='{name}',
    version="0.0.0",
    packages=find_packages(),
    zip_safe=False,
    install_requires=[
        "click-project",
    ],
    entry_points={{
        'console_scripts':
        [
            '{name}={name}.main:main',
        ]
    }},
)
""")
    package = (output / name)
    makedirs(package)
    createfile(
        package / "main.py", f"""#!/usr/bin/env python3
# -*- coding:utf-8 -*-

from click_project.setup import basic_entry_point, main
from click_project.decorators import command, argument, flag, option


@basic_entry_point(
__name__,
extra_command_packages=["{name}.commands"],
exclude_core_commands=["git-sync"],
)
def {name}(**kwargs):
    pass

if __name__ == "__main__":
    main()
""")
    createfile(package / "__init__.py", f"""#!/usr/bin/env python3""")
    commands = (package / "commands")
    makedirs(commands)
    (commands / "somecommand.py", """#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import click
from click_project.decorators import command, argument, flag, option
from click_project.log import get_logger


LOGGER = get_logger(__name__)


@command()
@argument("some-argument", help="some argument")
@flag("--some-flag/--no-some-flag", help="some flag")
@option("--some-option", help="some option")
def somecommand(some_argument, some_flag, some_option):
    "Some command"
    LOGGER.info(some_argument)
    LOGGER.info(some_flag)
    LOGGER.info(some_option)
""")
    print(f"Now, install {name} with `python3 -m pip install {name}`,"
          f" enable its completion with `{name} completion install`"
          f" and don't forget to have fun")
예제 #11
0
def remove(force, profile_source, plugin):
    """Remove the given custom command"""
    path = Path(profile_source.location) / "plugins" / (plugin + ".py")
    if force or click.confirm(f"This will remove {path}, are you sure ?"):
        rm(path)