codekingpro/portable-devtools
114k
1"""Android."""2 3from __future__ import annotations4 5import os6import re7import sys8from functools import lru_cache9from typing import cast10 11from .api import PlatformDirsABC12 13 14class Android(PlatformDirsABC):15 """16 Follows the guidance `from here <https://android.stackexchange.com/a/216132>`_.17 18 Makes use of the `appname <platformdirs.api.PlatformDirsABC.appname>`, `version19 <platformdirs.api.PlatformDirsABC.version>`, `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.20 21 """22 23 @property24 def user_data_dir(self) -> str:25 """:return: data directory tied to the user, e.g. ``/data/user/<userid>/<packagename>/files/<AppName>``"""26 return self._append_app_name_and_version(cast(str, _android_folder()), "files")27 28 @property29 def site_data_dir(self) -> str:30 """:return: data directory shared by users, same as `user_data_dir`"""31 return self.user_data_dir32 33 @property34 def user_config_dir(self) -> str:35 """36 :return: config directory tied to the user, e.g. \37 ``/data/user/<userid>/<packagename>/shared_prefs/<AppName>``38 """39 return self._append_app_name_and_version(cast(str, _android_folder()), "shared_prefs")40 41 @property42 def site_config_dir(self) -> str:43 """:return: config directory shared by the users, same as `user_config_dir`"""44 return self.user_config_dir45 46 @property47 def user_cache_dir(self) -> str:48 """:return: cache directory tied to the user, e.g.,``/data/user/<userid>/<packagename>/cache/<AppName>``"""49 return self._append_app_name_and_version(cast(str, _android_folder()), "cache")50 51 @property52 def site_cache_dir(self) -> str:53 """:return: cache directory shared by users, same as `user_cache_dir`"""54 return self.user_cache_dir55 56 @property57 def user_state_dir(self) -> str:58 """:return: state directory tied to the user, same as `user_data_dir`"""59 return self.user_data_dir60 61 @property62 def user_log_dir(self) -> str:63 """64 :return: log directory tied to the user, same as `user_cache_dir` if not opinionated else ``log`` in it,65 e.g. ``/data/user/<userid>/<packagename>/cache/<AppName>/log``66 """67 path = self.user_cache_dir68 if self.opinion:69 path = os.path.join(path, "log") # noqa: PTH11870 return path71 72 @property73 def user_documents_dir(self) -> str:74 """:return: documents directory tied to the user e.g. ``/storage/emulated/0/Documents``"""75 return _android_documents_folder()76 77 @property78 def user_downloads_dir(self) -> str:79 """:return: downloads directory tied to the user e.g. ``/storage/emulated/0/Downloads``"""80 return _android_downloads_folder()81 82 @property83 def user_pictures_dir(self) -> str:84 """:return: pictures directory tied to the user e.g. ``/storage/emulated/0/Pictures``"""85 return _android_pictures_folder()86 87 @property88 def user_videos_dir(self) -> str:89 """:return: videos directory tied to the user e.g. ``/storage/emulated/0/DCIM/Camera``"""90 return _android_videos_folder()91 92 @property93 def user_music_dir(self) -> str:94 """:return: music directory tied to the user e.g. ``/storage/emulated/0/Music``"""95 return _android_music_folder()96 97 @property98 def user_desktop_dir(self) -> str:99 """:return: desktop directory tied to the user e.g. ``/storage/emulated/0/Desktop``"""100 return "/storage/emulated/0/Desktop"101 102 @property103 def user_runtime_dir(self) -> str:104 """105 :return: runtime directory tied to the user, same as `user_cache_dir` if not opinionated else ``tmp`` in it,106 e.g. ``/data/user/<userid>/<packagename>/cache/<AppName>/tmp``107 """108 path = self.user_cache_dir109 if self.opinion:110 path = os.path.join(path, "tmp") # noqa: PTH118111 return path112 113 @property114 def site_runtime_dir(self) -> str:115 """:return: runtime directory shared by users, same as `user_runtime_dir`"""116 return self.user_runtime_dir117 118 119@lru_cache(maxsize=1)120def _android_folder() -> str | None:121 """:return: base folder for the Android OS or None if it cannot be found"""122 try:123 # First try to get a path to android app via pyjnius124 from jnius import autoclass # noqa: PLC0415125 126 context = autoclass("android.content.Context")127 result: str | None = context.getFilesDir().getParentFile().getAbsolutePath()128 except Exception: # noqa: BLE001129 # if fails find an android folder looking a path on the sys.path130 pattern = re.compile(r"/data/(data|user/\d+)/(.+)/files")131 for path in sys.path:132 if pattern.match(path):133 result = path.split("/files")[0]134 break135 else:136 result = None137 return result138 139 140@lru_cache(maxsize=1)141def _android_documents_folder() -> str:142 """:return: documents folder for the Android OS"""143 # Get directories with pyjnius144 try:145 from jnius import autoclass # noqa: PLC0415146 147 context = autoclass("android.content.Context")148 environment = autoclass("android.os.Environment")149 documents_dir: str = context.getExternalFilesDir(environment.DIRECTORY_DOCUMENTS).getAbsolutePath()150 except Exception: # noqa: BLE001151 documents_dir = "/storage/emulated/0/Documents"152 153 return documents_dir154 155 156@lru_cache(maxsize=1)157def _android_downloads_folder() -> str:158 """:return: downloads folder for the Android OS"""159 # Get directories with pyjnius160 try:161 from jnius import autoclass # noqa: PLC0415162 163 context = autoclass("android.content.Context")164 environment = autoclass("android.os.Environment")165 downloads_dir: str = context.getExternalFilesDir(environment.DIRECTORY_DOWNLOADS).getAbsolutePath()166 except Exception: # noqa: BLE001167 downloads_dir = "/storage/emulated/0/Downloads"168 169 return downloads_dir170 171 172@lru_cache(maxsize=1)173def _android_pictures_folder() -> str:174 """:return: pictures folder for the Android OS"""175 # Get directories with pyjnius176 try:177 from jnius import autoclass # noqa: PLC0415178 179 context = autoclass("android.content.Context")180 environment = autoclass("android.os.Environment")181 pictures_dir: str = context.getExternalFilesDir(environment.DIRECTORY_PICTURES).getAbsolutePath()182 except Exception: # noqa: BLE001183 pictures_dir = "/storage/emulated/0/Pictures"184 185 return pictures_dir186 187 188@lru_cache(maxsize=1)189def _android_videos_folder() -> str:190 """:return: videos folder for the Android OS"""191 # Get directories with pyjnius192 try:193 from jnius import autoclass # noqa: PLC0415194 195 context = autoclass("android.content.Context")196 environment = autoclass("android.os.Environment")197 videos_dir: str = context.getExternalFilesDir(environment.DIRECTORY_DCIM).getAbsolutePath()198 except Exception: # noqa: BLE001199 videos_dir = "/storage/emulated/0/DCIM/Camera"200 201 return videos_dir202 203 204@lru_cache(maxsize=1)205def _android_music_folder() -> str:206 """:return: music folder for the Android OS"""207 # Get directories with pyjnius208 try:209 from jnius import autoclass # noqa: PLC0415210 211 context = autoclass("android.content.Context")212 environment = autoclass("android.os.Environment")213 music_dir: str = context.getExternalFilesDir(environment.DIRECTORY_MUSIC).getAbsolutePath()214 except Exception: # noqa: BLE001215 music_dir = "/storage/emulated/0/Music"216 217 return music_dir218 219 220__all__ = [221 "Android",222]223 