From bfe4d10d9cccc902b71a06e75cb1d485ef2228d8 Mon Sep 17 00:00:00 2001 From: Morg42 <43153739+Morg42@users.noreply.github.com> Date: Wed, 6 Nov 2024 07:45:52 +0100 Subject: [PATCH] githubplugin: implemented plugin selection --- githubplugin/__init__.py | 77 +++++++++++++-------- githubplugin/webif/__init__.py | 26 ++++--- githubplugin/webif/templates/index.html | 92 ++++++++++++++++++++----- 3 files changed, 135 insertions(+), 60 deletions(-) diff --git a/githubplugin/__init__.py b/githubplugin/__init__.py index 93656895b..57f166c79 100644 --- a/githubplugin/__init__.py +++ b/githubplugin/__init__.py @@ -134,7 +134,7 @@ def set_repo(self) -> bool: self.git_repo = self.get_repo('smarthomeNG', self.repo) return True - def get_pull(self, number): + def get_pulls(self, fetch=False) -> bool: if not self._github: self.logger.error('error: Github object not initialized') return False @@ -142,27 +142,10 @@ def get_pull(self, number): if not self.git_repo: self.set_repo() - try: - pull = self.git_repo.get_pull(number=number) - except Exception: - return - - return { - 'title': pull.title, - 'pull': pull, - 'git_repo': pull.head.repo, - 'owner': pull.head.repo.owner.login, - 'repo': pull.head.repo.name, - 'branch': pull.head.ref - } - - def get_pulls(self) -> bool: - if not self._github: - self.logger.error('error: Github object not initialized') - return False - - if not self.git_repo: - self.set_repo() + # succeed if cached pulls present and fetch not requested + if not fetch: + if self.pulls != {}: + return True self.pulls = {} for pull in self.git_repo.get_pulls(): @@ -177,7 +160,7 @@ def get_pulls(self) -> bool: return True - def get_forks(self) -> bool: + def get_forks(self, fetch=False) -> bool: if not self._github: self.logger.error('error: Github object not initialized') return False @@ -185,13 +168,18 @@ def get_forks(self) -> bool: if not self.git_repo: self.set_repo() + # succeed if cached forks present and fetch not requested + if not fetch: + if self.forks != {}: + return True + self.forks = {} for fork in self.git_repo.get_forks(): self.forks[fork.full_name.split('/')[0]] = {'repo': fork} return True - def get_branches_from(self, fork=None, owner='') -> dict: + def get_branches_from(self, fork=None, owner='', fetch=False) -> dict: if fork is None and owner: try: @@ -201,6 +189,17 @@ def get_branches_from(self, fork=None, owner='') -> dict: if not fork: return {} + # if not specifically told to fetch from github - + if not fetch: + # try to get cached branches + try: + b_list = self.forks[fork.owner.login]['branches'] + except KeyError: + pass + else: + return b_list + + # fetch from github branches = fork.get_branches() b_list = {} for branch in branches: @@ -209,7 +208,7 @@ def get_branches_from(self, fork=None, owner='') -> dict: self.forks[fork.owner.login]['branches'] = b_list return b_list - def get_plugins_from(self, fork=None, owner='', branch='') -> list: + def get_plugins_from(self, fork=None, owner='', branch='', fetch=False) -> list: if not branch: return [] @@ -223,9 +222,26 @@ def get_plugins_from(self, fork=None, owner='', branch='') -> list: if not fork: return [] + # if not specifically told to fetch from github, - + if not fetch: + # try to get cached plugin list + try: + plugins = self.forks[fork.owner.login]['branches'][branch]['plugins'] + except KeyError: + pass + else: + return plugins + + # plugins not yet cached, fetch from github contents = fork.get_contents("", ref=branch) plugins = [item.path for item in contents if item.type == 'dir' and not item.path.startswith('.')] + try: + # add plugins to branch entry, if present + b = self.forks[fork.owner.login]['branches'][branch] + b['plugins'] = plugins + except KeyError: + pass return sorted(plugins) def get_all_branches(self) -> bool: @@ -551,17 +567,18 @@ def fetch_github_pulls(self) -> bool: """ fetch PRs from github API """ return self.gh.get_pulls() - def fetch_github_branches_from(self, fork=None, owner='') -> dict: + def fetch_github_branches_from(self, fork=None, owner='', fetch=False) -> dict: """ fetch branches for given fork from github API if fork is given as fork object, use this if owner is given and present in self.forks, use their fork object """ - self.logger.error(f'fetch github branches for {owner} or {fork}') - res = self.gh.get_branches_from(fork=fork, owner=owner) - self.logger.error(f'got {res}') - return res + return self.gh.get_branches_from(fork=fork, owner=owner, fetch=fetch) + + def fetch_github_plugins_from(self, fork=None, owner='', branch='', fetch=False) -> list: + """ fetch plugin names for selected fork/branch """ + return self.gh.get_plugins_from(fork=fork, owner=owner, branch=branch, fetch=fetch) def get_github_forks(self, owner=None) -> dict: """ return forks or single fork for given owner """ diff --git a/githubplugin/webif/__init__.py b/githubplugin/webif/__init__.py index 75c10965e..2a794d479 100644 --- a/githubplugin/webif/__init__.py +++ b/githubplugin/webif/__init__.py @@ -102,21 +102,25 @@ def index(self, reload=None, action=None, prnum=None, owner=None, branch=None, p @cherrypy.tools.json_out() @cherrypy.tools.json_in() def updateBranches(self): - # cl = cherrypy.request.headers['Content-Length'] - # if not cl: - # return - # try: - # rawbody = cherrypy.request.body.read(int(cl)) - # data = json.loads(rawbody) - # except Exception: - # return json = cherrypy.request.json - fork = json.get("fork") - if fork is not None and fork != '': - branches = self.plugin.fetch_github_branches_from(owner=fork) + owner = json.get("owner") + if owner is not None and owner != '': + branches = self.plugin.fetch_github_branches_from(owner=owner) if branches != {}: return {"operation": "request", "result": "success", "data": list(branches.keys())} + @cherrypy.expose + @cherrypy.tools.json_out() + @cherrypy.tools.json_in() + def updatePlugins(self): + json = cherrypy.request.json + owner = json.get("owner") + branch = json.get("branch") + if owner is not None and owner != '' and branch is not None and branch != '': + plugins = self.plugin.fetch_github_plugins_from(owner=owner, branch=branch) + if plugins != {}: + return {"operation": "request", "result": "success", "data": plugins} + # @cherrypy.expose # @cherrypy.tools.json_out() diff --git a/githubplugin/webif/templates/index.html b/githubplugin/webif/templates/index.html index 42ed40f24..b9e62e4fb 100644 --- a/githubplugin/webif/templates/index.html +++ b/githubplugin/webif/templates/index.html @@ -26,38 +26,41 @@ } } - function addOption(sel, val) { + function addOption(sel, val, def) { var option = document.createElement('option'); option.text = val; + if (def) { + option.selected = true; + } sel.add(option); } function setPR(selObj) { var PR = document.getElementById('pr').value; if (PR > 0) { - document.getElementById('fork').value = pulls[PR]['owner']; + document.getElementById('owner').value = pulls[PR]['owner']; var branch = document.getElementById('branch'); clearSelect(branch); addOption(branch, pulls[PR]['branch']); branch.value = pulls[PR]['branch']; document.getElementById('branch').disabled = false; + document.getElementById('btn-branch').disabled = false; + document.getElementById('btn-plugin').disabled = true; } } function updateBranches(selObj) { - var fork = document.getElementById('fork').value; + var owner = document.getElementById('owner').value; - if (fork != '') { - // alert(fork); + if (owner != '') { $.ajax({ type: "POST", url: "updateBranches", - data: JSON.stringify({'fork': fork}), + data: JSON.stringify({'owner': owner}), contentType: 'application/json', dataType: 'json', error: function(response) { alert("Fehler beim Übermitteln der Daten. Bitte shng-Log prüfen!"); - // document.getElementById('orphanModal').style.display = 'none'; }, success: function(response) { var item = document.getElementById('branch'); @@ -73,13 +76,57 @@ if (branch == 'master' || branch == 'main') { continue; } - addOption(item, branch); + addOption(item, branch, false); } } }) } } + function selectedBranch(selObj) { + if (document.getElementById('branch').value != '') { + document.getElementById('btn-branch').disabled = false; + } else { + document.getElementById('btn-branch').disabled = true; + document.getElementById('btn-plugin').disabled = true; + } + } + + function updatePlugins(selObj) { + var owner = document.getElementById('owner').value; + var branch = document.getElementById('branch').value; + + if (owner != '' && branch != '') { + $.ajax({ + type: "POST", + url: "updatePlugins", + data: JSON.stringify({'owner': owner, 'branch': branch}), + contentType: 'application/json', + dataType: 'json', + error: function(response) { + alert("Fehler beim Übermitteln der Daten. Bitte shng-Log prüfen!"); + }, + success: function(response) { + var item = document.getElementById('plugin'); + + // enable branch options + item.disabled = false; + + // clear options + clearSelect(item); + + // add all branches except master and main + for (const plugin of response['data']) { + addOption(item, plugin, plugin==branch); + } + + document.getElementById('btn-plugin').disabled = false; + } + }) + } + } + + {%- endblock pluginscripts %} @@ -153,31 +200,38 @@   - Fork: + Repo von: - + + {% for owner in forklist %} + {% endfor %} Branch: - - + + + + + Plugin: + + + + + - - {% endblock bodytab1 %}