mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-07 09:25:33 +00:00
We changed the comparison of version numbers a while ago, but this one slipped through. Using string comparison for version numbers is a bad idea... This addresses code review comments.
166 lines
6 KiB
Python
Executable file
166 lines
6 KiB
Python
Executable file
#!/usr/bin/python3
|
|
|
|
import json
|
|
import logging
|
|
import os
|
|
from pkg_resources import parse_version
|
|
|
|
from keyman_config import secure_lookup
|
|
from keyman_config.deprecated_decorator import deprecated
|
|
from keyman_config.get_kmp import InstallLocation, get_keyman_dir
|
|
from keyman_config.kmpmetadata import parseinfdata, parsemetadata
|
|
|
|
|
|
@deprecated('Use get_keyman_dir(area) instead')
|
|
def get_install_area_path(area):
|
|
return get_keyman_dir(area)
|
|
|
|
|
|
def get_installed_kmp(area):
|
|
"""
|
|
Get list of installed kmp in an install area.
|
|
|
|
Args:
|
|
area (InstallLocation): install area to check
|
|
InstallLocation.User: ~/.local/share/keyman
|
|
InstallLocation.Shared: /usr/local/share/keyman
|
|
InstallLocation.OS: /usr/share/keyman
|
|
Returns:
|
|
list: Installed kmp
|
|
dict: Keyboard
|
|
id (str): Keyboard ID
|
|
name (str): Keyboard name
|
|
kmpname (str): Keyboard name in local
|
|
version (str): available Keyboard version
|
|
kmpversion (str): installed Keyboard version
|
|
path (str): base path where keyboard is installed
|
|
description (str): Keyboard description
|
|
"""
|
|
check_paths = [get_keyman_dir(area)]
|
|
|
|
return get_installed_kmp_paths(check_paths)
|
|
|
|
|
|
def get_installed_kmp_paths(check_paths):
|
|
"""
|
|
Get list of installed kmp.
|
|
|
|
Args:
|
|
check_paths (list): list of paths to check
|
|
|
|
Returns:
|
|
list: Installed kmp
|
|
dict: Keyboard
|
|
packageID (str): kmp ID
|
|
keyboardID (str): Keyboard ID
|
|
name (str): Keyboard name
|
|
kmpname (str): Keyboard name in local
|
|
version (str): Keyboard version
|
|
kmpversion (str):
|
|
areapath (str): base path of area where kmp is installed
|
|
description (str): Keyboard description
|
|
has_kbjson (bool): Keyboard is in the json file
|
|
has_kboptions (bool): Keyboard uses options.htm form
|
|
"""
|
|
installed_keyboards = {}
|
|
for keymanpath in check_paths:
|
|
if os.path.isdir(keymanpath):
|
|
for o in os.listdir(keymanpath):
|
|
if os.path.isdir(os.path.join(keymanpath, o)) and o != "icons":
|
|
name = md_name = version = md_version = keyboardID = description = kbdata = None
|
|
info, system, options, keyboards, files = parsemetadata(os.path.join(keymanpath, o, "kmp.json"))
|
|
if not info:
|
|
info, system, options, keyboards, files = parseinfdata(os.path.join(keymanpath, o, "kmp.inf"))
|
|
has_kbjson = False
|
|
kbjson = os.path.join(keymanpath, o, o + ".json")
|
|
if os.path.isfile(kbjson):
|
|
try:
|
|
with open(kbjson, "r") as read_file:
|
|
kbdata = json.load(read_file)
|
|
if kbdata:
|
|
if 'description' in kbdata:
|
|
description = kbdata['description']
|
|
version = kbdata['version']
|
|
name = kbdata['name']
|
|
has_kbjson = True
|
|
except Exception as e:
|
|
logging.warning('Exception %s loading %s %s', type(e), kbjson, e.args)
|
|
if info:
|
|
md_version = secure_lookup(info, 'version', 'description')
|
|
md_name = secure_lookup(info, 'name', 'description')
|
|
if keyboards:
|
|
keyboardID = keyboards[0]['id']
|
|
else:
|
|
keyboardID = o
|
|
|
|
if not name:
|
|
version = md_version
|
|
name = md_name
|
|
|
|
has_kboptions = False
|
|
if files:
|
|
for fileinfo in files:
|
|
if fileinfo['name'] == "options.htm":
|
|
has_kboptions = True
|
|
break
|
|
installed_keyboards[o] = {
|
|
"packageID": o, "keyboardID": keyboardID, "name": name,
|
|
"kmpname": md_name, "version": version, "kmpversion": md_version,
|
|
"areapath": keymanpath, "description": description,
|
|
"has_kbjson": has_kbjson, "has_kboptions": has_kboptions}
|
|
return installed_keyboards
|
|
|
|
|
|
def get_kmp_version(packageID):
|
|
"""
|
|
Get version of the kmp for a package ID.
|
|
This return the highest version if installed in more than one area
|
|
|
|
Args:
|
|
packageID (dict): kmp ID
|
|
Returns:
|
|
str: kmp version if kmp ID is installed
|
|
None: if not found
|
|
"""
|
|
version = None
|
|
version = _get_kmp_version_internal(packageID, InstallLocation.OS, version)
|
|
version = _get_kmp_version_internal(packageID, InstallLocation.Shared, version)
|
|
version = _get_kmp_version_internal(packageID, InstallLocation.User, version)
|
|
return version
|
|
|
|
|
|
def _get_kmp_version_internal(packageId, location, previousVersion):
|
|
kmp = get_installed_kmp(location)
|
|
if packageId in kmp:
|
|
version = kmp[packageId]['kmpversion']
|
|
if not previousVersion or parse_version(previousVersion) < parse_version(version):
|
|
previousVersion = version
|
|
return previousVersion
|
|
|
|
|
|
def get_kmp_version_user(packageID):
|
|
"""
|
|
Get version of the kmp for a kmp ID.
|
|
This only checks the user area.
|
|
|
|
Args:
|
|
packageID (dict): kmp ID
|
|
Returns:
|
|
str: kmp version if kmp ID is installed
|
|
None: if not found
|
|
"""
|
|
return _get_kmp_version_internal(packageID, InstallLocation.User, None)
|
|
|
|
|
|
def get_kmp_version_shared(packageID):
|
|
"""
|
|
Get version of the kmp for a kmp ID.
|
|
This only checks the shared area.
|
|
|
|
Args:
|
|
packageID (dict): kmp ID
|
|
Returns:
|
|
str: kmp version if kmp ID is installed
|
|
None: if not found
|
|
"""
|
|
return _get_kmp_version_internal(packageID, InstallLocation.Shared, None)
|