图片解析应用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

210 lines
7.0 KiB

  1. """Android."""
  2. from __future__ import annotations
  3. import os
  4. import re
  5. import sys
  6. from functools import lru_cache
  7. from typing import cast
  8. from .api import PlatformDirsABC
  9. class Android(PlatformDirsABC):
  10. """
  11. Follows the guidance `from here <https://android.stackexchange.com/a/216132>`_. Makes use of the
  12. `appname <platformdirs.api.PlatformDirsABC.appname>`,
  13. `version <platformdirs.api.PlatformDirsABC.version>`,
  14. `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
  15. """
  16. @property
  17. def user_data_dir(self) -> str:
  18. """:return: data directory tied to the user, e.g. ``/data/user/<userid>/<packagename>/files/<AppName>``"""
  19. return self._append_app_name_and_version(cast(str, _android_folder()), "files")
  20. @property
  21. def site_data_dir(self) -> str:
  22. """:return: data directory shared by users, same as `user_data_dir`"""
  23. return self.user_data_dir
  24. @property
  25. def user_config_dir(self) -> str:
  26. """
  27. :return: config directory tied to the user, e.g. \
  28. ``/data/user/<userid>/<packagename>/shared_prefs/<AppName>``
  29. """
  30. return self._append_app_name_and_version(cast(str, _android_folder()), "shared_prefs")
  31. @property
  32. def site_config_dir(self) -> str:
  33. """:return: config directory shared by the users, same as `user_config_dir`"""
  34. return self.user_config_dir
  35. @property
  36. def user_cache_dir(self) -> str:
  37. """:return: cache directory tied to the user, e.g. e.g. ``/data/user/<userid>/<packagename>/cache/<AppName>``"""
  38. return self._append_app_name_and_version(cast(str, _android_folder()), "cache")
  39. @property
  40. def site_cache_dir(self) -> str:
  41. """:return: cache directory shared by users, same as `user_cache_dir`"""
  42. return self.user_cache_dir
  43. @property
  44. def user_state_dir(self) -> str:
  45. """:return: state directory tied to the user, same as `user_data_dir`"""
  46. return self.user_data_dir
  47. @property
  48. def user_log_dir(self) -> str:
  49. """
  50. :return: log directory tied to the user, same as `user_cache_dir` if not opinionated else ``log`` in it,
  51. e.g. ``/data/user/<userid>/<packagename>/cache/<AppName>/log``
  52. """
  53. path = self.user_cache_dir
  54. if self.opinion:
  55. path = os.path.join(path, "log") # noqa: PTH118
  56. return path
  57. @property
  58. def user_documents_dir(self) -> str:
  59. """:return: documents directory tied to the user e.g. ``/storage/emulated/0/Documents``"""
  60. return _android_documents_folder()
  61. @property
  62. def user_downloads_dir(self) -> str:
  63. """:return: downloads directory tied to the user e.g. ``/storage/emulated/0/Downloads``"""
  64. return _android_downloads_folder()
  65. @property
  66. def user_pictures_dir(self) -> str:
  67. """:return: pictures directory tied to the user e.g. ``/storage/emulated/0/Pictures``"""
  68. return _android_pictures_folder()
  69. @property
  70. def user_videos_dir(self) -> str:
  71. """:return: videos directory tied to the user e.g. ``/storage/emulated/0/DCIM/Camera``"""
  72. return _android_videos_folder()
  73. @property
  74. def user_music_dir(self) -> str:
  75. """:return: music directory tied to the user e.g. ``/storage/emulated/0/Music``"""
  76. return _android_music_folder()
  77. @property
  78. def user_runtime_dir(self) -> str:
  79. """
  80. :return: runtime directory tied to the user, same as `user_cache_dir` if not opinionated else ``tmp`` in it,
  81. e.g. ``/data/user/<userid>/<packagename>/cache/<AppName>/tmp``
  82. """
  83. path = self.user_cache_dir
  84. if self.opinion:
  85. path = os.path.join(path, "tmp") # noqa: PTH118
  86. return path
  87. @lru_cache(maxsize=1)
  88. def _android_folder() -> str | None:
  89. """:return: base folder for the Android OS or None if it cannot be found"""
  90. try:
  91. # First try to get path to android app via pyjnius
  92. from jnius import autoclass
  93. context = autoclass("android.content.Context")
  94. result: str | None = context.getFilesDir().getParentFile().getAbsolutePath()
  95. except Exception: # noqa: BLE001
  96. # if fails find an android folder looking path on the sys.path
  97. pattern = re.compile(r"/data/(data|user/\d+)/(.+)/files")
  98. for path in sys.path:
  99. if pattern.match(path):
  100. result = path.split("/files")[0]
  101. break
  102. else:
  103. result = None
  104. return result
  105. @lru_cache(maxsize=1)
  106. def _android_documents_folder() -> str:
  107. """:return: documents folder for the Android OS"""
  108. # Get directories with pyjnius
  109. try:
  110. from jnius import autoclass
  111. context = autoclass("android.content.Context")
  112. environment = autoclass("android.os.Environment")
  113. documents_dir: str = context.getExternalFilesDir(environment.DIRECTORY_DOCUMENTS).getAbsolutePath()
  114. except Exception: # noqa: BLE001
  115. documents_dir = "/storage/emulated/0/Documents"
  116. return documents_dir
  117. @lru_cache(maxsize=1)
  118. def _android_downloads_folder() -> str:
  119. """:return: downloads folder for the Android OS"""
  120. # Get directories with pyjnius
  121. try:
  122. from jnius import autoclass
  123. context = autoclass("android.content.Context")
  124. environment = autoclass("android.os.Environment")
  125. downloads_dir: str = context.getExternalFilesDir(environment.DIRECTORY_DOWNLOADS).getAbsolutePath()
  126. except Exception: # noqa: BLE001
  127. downloads_dir = "/storage/emulated/0/Downloads"
  128. return downloads_dir
  129. @lru_cache(maxsize=1)
  130. def _android_pictures_folder() -> str:
  131. """:return: pictures folder for the Android OS"""
  132. # Get directories with pyjnius
  133. try:
  134. from jnius import autoclass
  135. context = autoclass("android.content.Context")
  136. environment = autoclass("android.os.Environment")
  137. pictures_dir: str = context.getExternalFilesDir(environment.DIRECTORY_PICTURES).getAbsolutePath()
  138. except Exception: # noqa: BLE001
  139. pictures_dir = "/storage/emulated/0/Pictures"
  140. return pictures_dir
  141. @lru_cache(maxsize=1)
  142. def _android_videos_folder() -> str:
  143. """:return: videos folder for the Android OS"""
  144. # Get directories with pyjnius
  145. try:
  146. from jnius import autoclass
  147. context = autoclass("android.content.Context")
  148. environment = autoclass("android.os.Environment")
  149. videos_dir: str = context.getExternalFilesDir(environment.DIRECTORY_DCIM).getAbsolutePath()
  150. except Exception: # noqa: BLE001
  151. videos_dir = "/storage/emulated/0/DCIM/Camera"
  152. return videos_dir
  153. @lru_cache(maxsize=1)
  154. def _android_music_folder() -> str:
  155. """:return: music folder for the Android OS"""
  156. # Get directories with pyjnius
  157. try:
  158. from jnius import autoclass
  159. context = autoclass("android.content.Context")
  160. environment = autoclass("android.os.Environment")
  161. music_dir: str = context.getExternalFilesDir(environment.DIRECTORY_MUSIC).getAbsolutePath()
  162. except Exception: # noqa: BLE001
  163. music_dir = "/storage/emulated/0/Music"
  164. return music_dir
  165. __all__ = [
  166. "Android",
  167. ]