-
-
Notifications
You must be signed in to change notification settings - Fork 412
wxGUI/extensions: fix reinstall/uninstall multi-addon e.g. wx.metadata #2452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
9964a65
e5df0b5
6afb98b
1df9699
faac751
bc00a03
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,7 @@ | |
| """ | ||
|
|
||
| import os | ||
| import re | ||
| import sys | ||
| import atexit | ||
| import subprocess | ||
|
|
@@ -32,10 +33,14 @@ | |
| import io | ||
| from tempfile import NamedTemporaryFile | ||
| from pathlib import Path | ||
| from urllib.parse import urlparse | ||
|
|
||
| import xml.etree.ElementTree as etree | ||
|
|
||
| from .utils import KeyValue, parse_key_val, basename, encode, decode, try_remove | ||
| from grass.exceptions import ScriptError, CalledModuleError | ||
| from grass.grassdb.manage import resolve_mapset_path | ||
| from grass.utils.download import download_file | ||
|
|
||
|
|
||
| # subprocess wrapper that uses shell on Windows | ||
|
|
@@ -2054,6 +2059,74 @@ def create_environment(gisdbase, location, mapset, env=None): | |
| return f.name, env | ||
|
|
||
|
|
||
| def find_addon_name(addons, url=None): | ||
| """Find correct addon name if addon is a multi-addon | ||
| e.g. wx.metadata contains multiple modules g.gui.cswbrowser etc. | ||
|
|
||
| Examples: | ||
| - for the g.gui.cswbrowser module the wx.metadata addon name is | ||
| returned | ||
| - for the i.sentinel.download module the i.sentinel addon name is | ||
| returned | ||
| etc. | ||
|
|
||
| :param list addons: list of individual addon modules | ||
| :param str url: Addons modules.xml file URL | ||
|
|
||
| :return: list of unique simple and multi addons | ||
|
|
||
| >>> addons = find_addon_name( | ||
| ... addons=[ | ||
| ... "g.gui.metadata", | ||
| ... "g.gui.cswbrowser", | ||
| ... "db.csw.run", | ||
| ... "db.csw.harvest", | ||
| ... "db.csw.admin", | ||
| ... "v.info.iso", | ||
| ... "r.info.iso", | ||
| ... "t.info.iso", | ||
| ... "db.join", | ||
| ... ] | ||
| ... ) | ||
| >>> addons.sort() | ||
| >>> addons | ||
| ['db.join', 'wx.metadata'] | ||
| """ | ||
|
Comment on lines
+2078
to
+2094
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure I understand this example result, why only those 2 addons?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
wx.metadata is multi-addon (contains g.gui.metadata addon, g.gui.cswbrowser addon and etc.), we need identify multi-addon name which is in this example wx.metadata if user want uninstalling multi-addon (see GUI Manage installed extension dialog list of installed addon after you install some multi-addon e.g. wx.metadata) |
||
| if not url: | ||
| grass_version = os.getenv("GRASS_VERSION", "unknown") | ||
| if grass_version != "unknown": | ||
| major, minor, patch = grass_version.split(".") | ||
| else: | ||
| fatal(_("Unable to get GRASS GIS version.")) | ||
| url = "https://grass.osgeo.org/addons/grass{major}/modules.xml".format( | ||
| major=major, | ||
| ) | ||
| response = download_file( | ||
| url=url, | ||
| response_format="application/xml", | ||
| file_name=os.path.basename(urlparse(url).path), | ||
| ) | ||
| tree = etree.fromstring(response.read()) | ||
Check warningCode scanning / Bandit Using xml.etree.ElementTree.fromstring to parse untrusted XML data is known to be vulnerable to XML attacks. Replace xml.etree.ElementTree.fromstring with its defusedxml equivalent function or make sure defusedxml.defuse_stdlib() is called
Using xml.etree.ElementTree.fromstring to parse untrusted XML data is known to be vulnerable to XML attacks. Replace xml.etree.ElementTree.fromstring with its defusedxml equivalent function or make sure defusedxml.defuse_stdlib() is called
|
||
| result = [] | ||
| for addon in addons: | ||
| found = False | ||
| addon_pattern = re.compile(r".*{}$".format(addon)) | ||
| for i in tree: | ||
| for f in i.findall(".//binary/file"): | ||
| if re.match(addon_pattern, f.text): | ||
| result.append(i.attrib["name"]) | ||
| found = True | ||
| break | ||
| if not found: | ||
| warning( | ||
| _( | ||
| "The addon <{}> was not found among the official" | ||
| " addons.".format(addon) | ||
| ), | ||
| ) | ||
| return list(set(result)) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| import doctest | ||
|
|
||
|
|
||
Check notice
Code scanning / Bandit
Using xml.etree.ElementTree to parse untrusted XML data is known to be vulnerable to XML attacks. Replace xml.etree.ElementTree with the equivalent defusedxml package, or make sure defusedxml.defuse_stdlib() is called.