From 991725d325ad753a8fc41b46e38caf6e315fa24c Mon Sep 17 00:00:00 2001 From: YariKartoshe4ka Date: Fri, 9 Jul 2021 12:22:37 +0300 Subject: [PATCH 1/2] Adding android support --- appdirs.py | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/appdirs.py b/appdirs.py index 08abda8..6c294e1 100644 --- a/appdirs.py +++ b/appdirs.py @@ -36,11 +36,11 @@ # are actually checked for and the rest of the module expects # *sys.platform* style strings. system = 'linux2' +elif os.getenv('EXTERNAL_STORAGE'): + system = 'android' else: system = sys.platform - - def user_data_dir(appname=None, appauthor=None, version=None, roaming=False): r"""Return full path to the user-specific data dir for this application. @@ -69,6 +69,7 @@ def user_data_dir(appname=None, appauthor=None, version=None, roaming=False): Win XP (roaming): C:\Documents and Settings\\Local Settings\Application Data\\ Win 7 (not roaming): C:\Users\\AppData\Local\\ Win 7 (roaming): C:\Users\\AppData\Roaming\\ + Android: /data/user///files/ For Unix, we follow the XDG spec and support $XDG_DATA_HOME. That means, by default "~/.local/share/". @@ -87,6 +88,10 @@ def user_data_dir(appname=None, appauthor=None, version=None, roaming=False): path = os.path.expanduser('~/Library/Application Support/') if appname: path = os.path.join(path, appname) + elif system == 'android': + path = os.path.join(_get_android_folder(), 'files') + if appname: + path = os.path.join(path, appname) else: path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share")) if appname: @@ -122,6 +127,7 @@ def site_data_dir(appname=None, appauthor=None, version=None, multipath=False): Win XP: C:\Documents and Settings\All Users\Application Data\\ Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) Win 7: C:\ProgramData\\ # Hidden, but writeable on Win 7. + Android: same as user_data_dir For Unix, this is using the $XDG_DATA_DIRS[0] default. @@ -140,6 +146,8 @@ def site_data_dir(appname=None, appauthor=None, version=None, multipath=False): path = os.path.expanduser('/Library/Application Support') if appname: path = os.path.join(path, appname) + elif system == 'android': + path = user_data_dir(appname, appauthor, version, False) else: # XDG default for $XDG_DATA_DIRS # only first, if multipath is False @@ -187,6 +195,7 @@ def user_config_dir(appname=None, appauthor=None, version=None, roaming=False): Mac OS X: ~/Library/Preferences/ Unix: ~/.config/ # or in $XDG_CONFIG_HOME, if defined Win *: same as user_data_dir + Android: /data/user///shared_prefs/ For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. That means, by default "~/.config/". @@ -197,6 +206,10 @@ def user_config_dir(appname=None, appauthor=None, version=None, roaming=False): path = os.path.expanduser('~/Library/Preferences/') if appname: path = os.path.join(path, appname) + elif system == 'android': + path = os.path.join(_get_android_folder(), 'shared_prefs') + if appname: + path = os.path.join(path, appname) else: path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config")) if appname: @@ -231,6 +244,7 @@ def site_config_dir(appname=None, appauthor=None, version=None, multipath=False) $XDG_CONFIG_DIRS Win *: same as site_data_dir Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + Android: same as user_config_dir For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False @@ -244,6 +258,8 @@ def site_config_dir(appname=None, appauthor=None, version=None, multipath=False) path = os.path.expanduser('/Library/Preferences') if appname: path = os.path.join(path, appname) + elif system == 'android': + path = user_config_dir(appname, appauthor, version, False) else: # XDG default for $XDG_CONFIG_DIRS # only first, if multipath is False @@ -284,6 +300,7 @@ def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True): Unix: ~/.cache/ (XDG default) Win XP: C:\Documents and Settings\\Local Settings\Application Data\\\Cache Vista: C:\Users\\AppData\Local\\\Cache + Android: /data/user///cache/ On Windows the only suggestion in the MSDN docs is that local settings go in the `CSIDL_LOCAL_APPDATA` directory. This is identical to the non-roaming @@ -309,6 +326,8 @@ def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True): path = os.path.expanduser('~/Library/Caches') if appname: path = os.path.join(path, appname) + elif system == 'android': + path = os.path.join(_get_android_folder(), 'cache') else: path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache')) if appname: @@ -343,13 +362,14 @@ def user_state_dir(appname=None, appauthor=None, version=None, roaming=False): Mac OS X: same as user_data_dir Unix: ~/.local/state/ # or in $XDG_STATE_HOME, if defined Win *: same as user_data_dir + Android: same as user_data_dir For Unix, we follow this Debian proposal to extend the XDG spec and support $XDG_STATE_HOME. That means, by default "~/.local/state/". """ - if system in ["win32", "darwin"]: + if system in ["win32", "darwin", "android"]: path = user_data_dir(appname, appauthor, None, roaming) else: path = os.getenv('XDG_STATE_HOME', os.path.expanduser("~/.local/state")) @@ -383,6 +403,7 @@ def user_log_dir(appname=None, appauthor=None, version=None, opinion=True): Unix: ~/.cache//log # or under $XDG_CACHE_HOME if defined Win XP: C:\Documents and Settings\\Local Settings\Application Data\\\Logs Vista: C:\Users\\AppData\Local\\\Logs + Android: /data/user///cache//log On Windows the only suggestion in the MSDN docs is that local settings go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in @@ -544,6 +565,23 @@ def _get_win_folder_from_environ(csidl_name): return os.environ[env_var_name] +def _get_android_folder_with_jnius(): + from jnius import autoclass + + Context = autoclass('android.content.Context') + return Context.getFilesDir().getParentFile().getAbsolutePath() + +def _get_android_folder_brute_path(): + from re import match + + pattern = r'/data/(data|user/\d+)/(.+)/files' + + for path in sys.path: + if match(pattern, path): + return path.split('/files')[0] + + raise OSError('Cannot find path to android app folder') + if system == "win32": try: from ctypes import windll @@ -565,6 +603,14 @@ def _get_win_folder_from_environ(csidl_name): else: _get_win_folder = _get_win_folder_with_ctypes +elif system == "android": + try: + from jnius import autoclass + except ImportError: + _get_android_folder = _get_android_folder_brute_path + else: + _get_android_folder = _get_android_folder_with_jnius + #---- self test code From fb97e62f74d43d645157252599036527c6dae329 Mon Sep 17 00:00:00 2001 From: YariKartoshe4ka Date: Fri, 9 Jul 2021 12:54:35 +0300 Subject: [PATCH 2/2] Pydriod jnius bug resolution --- appdirs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appdirs.py b/appdirs.py index 6c294e1..4e30066 100644 --- a/appdirs.py +++ b/appdirs.py @@ -605,8 +605,8 @@ def _get_android_folder_brute_path(): elif system == "android": try: - from jnius import autoclass - except ImportError: + _get_android_folder_with_jnius() + except: _get_android_folder = _get_android_folder_brute_path else: _get_android_folder = _get_android_folder_with_jnius