nc-py-api 0.17.0__tar.gz → 0.17.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/CHANGELOG.md +10 -0
  2. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/PKG-INFO +1 -1
  3. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/_version.py +1 -1
  4. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/apps.py +0 -13
  5. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/ex_app/__init__.py +1 -0
  6. nc_py_api-0.17.1/nc_py_api/ex_app/logging.py +46 -0
  7. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/nextcloud.py +24 -12
  8. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/.gitignore +0 -0
  9. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/AUTHORS +0 -0
  10. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/LICENSE.txt +0 -0
  11. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/README.md +0 -0
  12. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/__init__.py +0 -0
  13. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/_deffered_error.py +0 -0
  14. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/_exceptions.py +0 -0
  15. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/_misc.py +0 -0
  16. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/_preferences.py +0 -0
  17. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/_preferences_ex.py +0 -0
  18. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/_session.py +0 -0
  19. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/_talk_api.py +0 -0
  20. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/_theming.py +0 -0
  21. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/activity.py +0 -0
  22. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/calendar.py +0 -0
  23. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/ex_app/defs.py +0 -0
  24. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/ex_app/events_listener.py +0 -0
  25. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/ex_app/integration_fastapi.py +0 -0
  26. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/ex_app/misc.py +0 -0
  27. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/ex_app/occ_commands.py +0 -0
  28. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/ex_app/persist_transformers_cache.py +0 -0
  29. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/ex_app/providers/__init__.py +0 -0
  30. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/ex_app/providers/providers.py +0 -0
  31. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/ex_app/providers/task_processing.py +0 -0
  32. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/ex_app/ui/__init__.py +0 -0
  33. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/ex_app/ui/files_actions.py +0 -0
  34. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/ex_app/ui/resources.py +0 -0
  35. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/ex_app/ui/settings.py +0 -0
  36. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/ex_app/ui/top_menu.py +0 -0
  37. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/ex_app/ui/ui.py +0 -0
  38. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/ex_app/uvicorn_fastapi.py +0 -0
  39. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/files/__init__.py +0 -0
  40. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/files/_files.py +0 -0
  41. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/files/files.py +0 -0
  42. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/files/files_async.py +0 -0
  43. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/files/sharing.py +0 -0
  44. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/loginflow_v2.py +0 -0
  45. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/notes.py +0 -0
  46. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/notifications.py +0 -0
  47. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/options.py +0 -0
  48. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/talk.py +0 -0
  49. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/talk_bot.py +0 -0
  50. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/user_status.py +0 -0
  51. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/users.py +0 -0
  52. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/users_groups.py +0 -0
  53. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/weather_status.py +0 -0
  54. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/nc_py_api/webhooks.py +0 -0
  55. {nc_py_api-0.17.0 → nc_py_api-0.17.1}/pyproject.toml +0 -0
@@ -2,6 +2,16 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.17.1 - 2024-09-06]
6
+
7
+ ### Added
8
+
9
+ - NextcloudApp: `setup_nextcloud_logging` function to support transparently sending logs to Nextcloud. #294
10
+
11
+ ### Fixed
12
+
13
+ - NextcloudApp: `nc.log` now suppresses all exceptions to safe call it anywhere(for example in exception handlers). #293
14
+
5
15
  ## [0.17.0 - 2024-09-05]
6
16
 
7
17
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: nc-py-api
3
- Version: 0.17.0
3
+ Version: 0.17.1
4
4
  Summary: Nextcloud Python Framework
5
5
  Project-URL: Changelog, https://github.com/cloud-py-api/nc_py_api/blob/main/CHANGELOG.md
6
6
  Project-URL: Documentation, https://cloud-py-api.github.io/nc_py_api/
@@ -1,3 +1,3 @@
1
1
  """Version of nc_py_api."""
2
2
 
3
- __version__ = "0.17.0"
3
+ __version__ = "0.17.1"
@@ -1,7 +1,6 @@
1
1
  """Nextcloud API for working with applications."""
2
2
 
3
3
  import dataclasses
4
- import datetime
5
4
 
6
5
  from ._misc import require_capabilities
7
6
  from ._session import AsyncNcSessionBasic, NcSessionBasic
@@ -34,18 +33,6 @@ class ExAppInfo:
34
33
  """Flag indicating if the application enabled."""
35
34
  return bool(self._raw_data["enabled"])
36
35
 
37
- @property
38
- def last_check_time(self) -> datetime.datetime:
39
- """Time of the last successful application check."""
40
- return datetime.datetime.utcfromtimestamp(int(self._raw_data["last_check_time"])).replace(
41
- tzinfo=datetime.timezone.utc
42
- )
43
-
44
- @property
45
- def system(self) -> bool:
46
- """**DEPRECATED** Flag indicating if the application is a system application."""
47
- return True
48
-
49
36
  def __repr__(self):
50
37
  return f"<{self.__class__.__name__} id={self.app_id}, ver={self.version}>"
51
38
 
@@ -10,6 +10,7 @@ from .integration_fastapi import (
10
10
  set_handlers,
11
11
  talk_bot_msg,
12
12
  )
13
+ from .logging import setup_nextcloud_logging
13
14
  from .misc import (
14
15
  get_computation_device,
15
16
  get_model_path,
@@ -0,0 +1,46 @@
1
+ """Transparent logging support to store logs in the nextcloud.log."""
2
+
3
+ import logging
4
+ import threading
5
+
6
+ from ..nextcloud import NextcloudApp
7
+ from .defs import LogLvl
8
+
9
+ LOGLVL_MAP = {
10
+ logging.NOTSET: LogLvl.DEBUG,
11
+ logging.DEBUG: LogLvl.DEBUG,
12
+ logging.INFO: LogLvl.INFO,
13
+ logging.WARNING: LogLvl.WARNING,
14
+ logging.ERROR: LogLvl.ERROR,
15
+ logging.CRITICAL: LogLvl.FATAL,
16
+ }
17
+
18
+ THREAD_LOCAL = threading.local()
19
+
20
+
21
+ class _NextcloudLogsHandler(logging.Handler):
22
+ def __init__(self):
23
+ super().__init__()
24
+
25
+ def emit(self, record):
26
+ if THREAD_LOCAL.__dict__.get("nc_py_api.loghandler", False):
27
+ return
28
+
29
+ try:
30
+ THREAD_LOCAL.__dict__["nc_py_api.loghandler"] = True
31
+ log_entry = self.format(record)
32
+ log_level = record.levelno
33
+ NextcloudApp().log(LOGLVL_MAP.get(log_level, LogLvl.FATAL), log_entry, fast_send=True)
34
+ except Exception: # noqa pylint: disable=broad-exception-caught
35
+ self.handleError(record)
36
+ finally:
37
+ THREAD_LOCAL.__dict__["nc_py_api.loghandler"] = False
38
+
39
+
40
+ def setup_nextcloud_logging(logger_name: str | None = None, logging_level: int = logging.DEBUG):
41
+ """Function to easily send all or selected log entries to Nextcloud."""
42
+ logger = logging.getLogger(logger_name)
43
+ nextcloud_handler = _NextcloudLogsHandler()
44
+ nextcloud_handler.setLevel(logging_level)
45
+ logger.addHandler(nextcloud_handler)
46
+ return nextcloud_handler
@@ -348,13 +348,18 @@ class NextcloudApp(_NextcloudBasic):
348
348
  return bool(self._session.ocs("GET", "/ocs/v1.php/apps/app_api/ex-app/state"))
349
349
  return False
350
350
 
351
- def log(self, log_lvl: LogLvl, content: str) -> None:
351
+ def log(self, log_lvl: LogLvl, content: str, fast_send: bool = False) -> None:
352
352
  """Writes log to the Nextcloud log file."""
353
- if self.check_capabilities("app_api"):
354
- return
355
- if int(log_lvl) < self.capabilities["app_api"].get("loglevel", 0):
356
- return
357
- self._session.ocs("POST", f"{self._session.ae_url}/log", json={"level": int(log_lvl), "message": content})
353
+ int_log_lvl = int(log_lvl)
354
+ if int_log_lvl < 0 or int_log_lvl > 4:
355
+ raise ValueError("Invalid `log_lvl` value")
356
+ if not fast_send:
357
+ if self.check_capabilities("app_api"):
358
+ return
359
+ if int_log_lvl < self.capabilities["app_api"].get("loglevel", 0):
360
+ return
361
+ with contextlib.suppress(Exception):
362
+ self._session.ocs("POST", f"{self._session.ae_url}/log", json={"level": int_log_lvl, "message": content})
358
363
 
359
364
  def users_list(self) -> list[str]:
360
365
  """Returns list of users on the Nextcloud instance."""
@@ -478,13 +483,20 @@ class AsyncNextcloudApp(_AsyncNextcloudBasic):
478
483
  return bool(await self._session.ocs("GET", "/ocs/v1.php/apps/app_api/ex-app/state"))
479
484
  return False
480
485
 
481
- async def log(self, log_lvl: LogLvl, content: str) -> None:
486
+ async def log(self, log_lvl: LogLvl, content: str, fast_send: bool = False) -> None:
482
487
  """Writes log to the Nextcloud log file."""
483
- if await self.check_capabilities("app_api"):
484
- return
485
- if int(log_lvl) < (await self.capabilities)["app_api"].get("loglevel", 0):
486
- return
487
- await self._session.ocs("POST", f"{self._session.ae_url}/log", json={"level": int(log_lvl), "message": content})
488
+ int_log_lvl = int(log_lvl)
489
+ if int_log_lvl < 0 or int_log_lvl > 4:
490
+ raise ValueError("Invalid `log_lvl` value")
491
+ if not fast_send:
492
+ if await self.check_capabilities("app_api"):
493
+ return
494
+ if int_log_lvl < (await self.capabilities)["app_api"].get("loglevel", 0):
495
+ return
496
+ with contextlib.suppress(Exception):
497
+ await self._session.ocs(
498
+ "POST", f"{self._session.ae_url}/log", json={"level": int_log_lvl, "message": content}
499
+ )
488
500
 
489
501
  async def users_list(self) -> list[str]:
490
502
  """Returns list of users on the Nextcloud instance."""
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes