extensions.py 3.1 KB
Newer Older
1 2 3 4 5 6 7 8 9
import os
import sys
import traceback

import git

from modules import paths, shared

extensions = []
10
extensions_dir = os.path.join(paths.data_path, "extensions")
A
AUTOMATIC 已提交
11
extensions_builtin_dir = os.path.join(paths.script_path, "extensions-builtin")
12

13 14
if not os.path.exists(extensions_dir):
    os.makedirs(extensions_dir)
15 16 17 18 19 20

def active():
    return [x for x in extensions if x.enabled]


class Extension:
A
AUTOMATIC 已提交
21
    def __init__(self, name, path, enabled=True, is_builtin=False):
22 23 24 25 26
        self.name = name
        self.path = path
        self.enabled = enabled
        self.status = ''
        self.can_update = False
A
AUTOMATIC 已提交
27
        self.is_builtin = is_builtin
28 29 30 31 32 33 34 35 36 37 38 39

        repo = None
        try:
            if os.path.exists(os.path.join(path, ".git")):
                repo = git.Repo(path)
        except Exception:
            print(f"Error reading github repository info from {path}:", file=sys.stderr)
            print(traceback.format_exc(), file=sys.stderr)

        if repo is None or repo.bare:
            self.remote = None
        else:
40 41 42 43 44
            try:
                self.remote = next(repo.remote().urls, None)
                self.status = 'unknown'
            except Exception:
                self.remote = None
45 46 47 48 49 50 51 52 53 54

    def list_files(self, subdir, extension):
        from modules import scripts

        dirpath = os.path.join(self.path, subdir)
        if not os.path.isdir(dirpath):
            return []

        res = []
        for filename in sorted(os.listdir(dirpath)):
55
            res.append(scripts.ScriptFile(self.path, filename, os.path.join(dirpath, filename)))
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71

        res = [x for x in res if os.path.splitext(x.path)[1].lower() == extension and os.path.isfile(x.path)]

        return res

    def check_updates(self):
        repo = git.Repo(self.path)
        for fetch in repo.remote().fetch("--dry-run"):
            if fetch.flags != fetch.HEAD_UPTODATE:
                self.can_update = True
                self.status = "behind"
                return

        self.can_update = False
        self.status = "latest"

72
    def fetch_and_reset_hard(self):
73
        repo = git.Repo(self.path)
74 75 76 77
        # Fix: `error: Your local changes to the following files would be overwritten by merge`,
        # because WSL2 Docker set 755 file permissions instead of 644, this results to the error.
        repo.git.fetch('--all')
        repo.git.reset('--hard', 'origin')
78 79 80 81 82 83 84 85


def list_extensions():
    extensions.clear()

    if not os.path.isdir(extensions_dir):
        return

A
AUTOMATIC 已提交
86 87 88 89
    paths = []
    for dirname in [extensions_dir, extensions_builtin_dir]:
        if not os.path.isdir(dirname):
            return
90

A
AUTOMATIC 已提交
91 92 93 94 95 96 97 98 99
        for extension_dirname in sorted(os.listdir(dirname)):
            path = os.path.join(dirname, extension_dirname)
            if not os.path.isdir(path):
                continue

            paths.append((extension_dirname, path, dirname == extensions_builtin_dir))

    for dirname, path, is_builtin in paths:
        extension = Extension(name=dirname, path=path, enabled=dirname not in shared.opts.disabled_extensions, is_builtin=is_builtin)
100
        extensions.append(extension)
D
d8ahazard 已提交
101