xenoslib 0.1.29.24__tar.gz → 0.1.30__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 (24) hide show
  1. {xenoslib-0.1.29.24/xenoslib.egg-info → xenoslib-0.1.30}/PKG-INFO +1 -1
  2. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/xenoslib/about.py +1 -1
  3. xenoslib-0.1.30/xenoslib/extend.py +198 -0
  4. xenoslib-0.1.30/xenoslib/tools/__init__.py +1 -0
  5. xenoslib-0.1.29.24/xenoslib/extend.py → xenoslib-0.1.30/xenoslib/tools/config_loader.py +0 -183
  6. {xenoslib-0.1.29.24 → xenoslib-0.1.30/xenoslib.egg-info}/PKG-INFO +1 -1
  7. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/xenoslib.egg-info/SOURCES.txt +3 -1
  8. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/LICENSE +0 -0
  9. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/README.md +0 -0
  10. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/setup.cfg +0 -0
  11. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/setup.py +0 -0
  12. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/xenoslib/__init__.py +0 -0
  13. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/xenoslib/__main__.py +0 -0
  14. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/xenoslib/base.py +0 -0
  15. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/xenoslib/dev.py +0 -0
  16. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/xenoslib/linux.py +0 -0
  17. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/xenoslib/mail.py +0 -0
  18. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/xenoslib/mock.py +0 -0
  19. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/xenoslib/onedrive.py +0 -0
  20. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/xenoslib/win_trayicon.py +0 -0
  21. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/xenoslib/windows.py +0 -0
  22. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/xenoslib.egg-info/dependency_links.txt +0 -0
  23. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/xenoslib.egg-info/requires.txt +0 -0
  24. {xenoslib-0.1.29.24 → xenoslib-0.1.30}/xenoslib.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xenoslib
3
- Version: 0.1.29.24
3
+ Version: 0.1.30
4
4
  Summary: Xenos' common lib
5
5
  Home-page: https://github.com/XenosLu/xenoslib.git
6
6
  Author: Xenocider
@@ -4,4 +4,4 @@ __url__ = "https://github.com/XenosLu/xenoslib.git"
4
4
  __author__ = "Xenocider"
5
5
  __author_email__ = "xenos.lu@gmail.com"
6
6
  __license__ = "MIT License"
7
- __version__ = "0.1.29.24"
7
+ __version__ = "0.1.30"
@@ -0,0 +1,198 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ import os
4
+ import sys
5
+ import logging
6
+
7
+ import yaml
8
+ import requests
9
+
10
+ from xenoslib.tools import ConfigLoader # noqa compactive
11
+
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class YamlConfig(dict):
17
+ """A thread unsafe yaml file config utility , can work as a dict except __init__"""
18
+
19
+ def __getattr__(self, key):
20
+ return self.get(key)
21
+
22
+ def __setattr__(self, name, value):
23
+ try:
24
+ getattr(super(), name)
25
+ except AttributeError as exc:
26
+ if str(exc).startswith("'super' object has no attribute "):
27
+ self[name] = value
28
+ return
29
+ raise exc
30
+ raise AttributeError(f"'{__class__.__name__}' object attribute '{name}' is read-only")
31
+
32
+ def __str__(self):
33
+ return yaml.safe_dump(self.copy(), allow_unicode=True)
34
+
35
+ def __repr__(self):
36
+ return repr(str(self))
37
+
38
+ def __init__(self, conf_path=None):
39
+ pass
40
+
41
+ def __new__(cls, conf_path="config.yml", *args, **kwargs):
42
+ if not hasattr(cls, "_instances"):
43
+ cls._instances = {}
44
+ if cls._instances.get(conf_path) is None:
45
+ cls._instances[conf_path] = super().__new__(cls)
46
+ super().__setattr__(cls._instances[conf_path], "_conf_path", conf_path)
47
+ cls._instances[conf_path]._load_conf()
48
+ return cls._instances[conf_path]
49
+
50
+ def _load_conf(self):
51
+ if os.path.exists(self._conf_path):
52
+ with open(self._conf_path, encoding="utf-8") as r:
53
+ self.update(yaml.safe_load(r))
54
+
55
+ def save(self):
56
+ data = str(self)
57
+ with open(self._conf_path, "w", encoding="utf-8") as w:
58
+ w.write(data)
59
+ # yaml.safe_dump(self.copy(), w, allow_unicode=True)
60
+
61
+
62
+ class RequestAdapter:
63
+ def request(self, method, path, *args, **kwargs):
64
+ """to-do: support stream=True"""
65
+ url = f"{self.base_url}/{path}"
66
+ logger.debug(url)
67
+ response = self.session.request(method, url, *args, **kwargs)
68
+ logger.debug(response.text)
69
+ response.raise_for_status()
70
+ try:
71
+ return response.json()
72
+ except Exception as exc:
73
+ logger.debug(exc)
74
+ return response
75
+
76
+ def get(self, path, *args, **kwargs):
77
+ return self.request("get", path, *args, **kwargs)
78
+
79
+ def post(self, path, *args, **kwargs):
80
+ return self.request("post", path, *args, **kwargs)
81
+
82
+ def put(self, path, *args, **kwargs):
83
+ return self.request("put", path, *args, **kwargs)
84
+
85
+ def delete(self, path, *args, **kwargs):
86
+ return self.request("delete", path, *args, **kwargs)
87
+
88
+ def patch(self, path, *args, **kwargs):
89
+ return self.request("patch", path, *args, **kwargs)
90
+
91
+ def head(self, path, *args, **kwargs):
92
+ return self.request("head", path, *args, **kwargs)
93
+
94
+ def __init__(self):
95
+ self.session = requests.Session()
96
+
97
+
98
+ def del_to_recyclebin(filepath, on_fail_delete=False):
99
+ """delete file to recyclebin if possible"""
100
+ if not sys.platform == "win32":
101
+ if on_fail_delete:
102
+ os.remove(filepath)
103
+ return True
104
+ return False
105
+ from win32com.shell import shell, shellcon
106
+
107
+ res, _ = shell.SHFileOperation(
108
+ (
109
+ 0,
110
+ shellcon.FO_DELETE,
111
+ filepath,
112
+ None,
113
+ shellcon.FOF_SILENT | shellcon.FOF_ALLOWUNDO | shellcon.FOF_NOCONFIRMATION,
114
+ None,
115
+ None,
116
+ )
117
+ )
118
+ return res == 0
119
+
120
+
121
+ def send_notify(msg, key):
122
+ """send a message for ifttt"""
123
+ url = f"https://maker.ifttt.com/trigger/message/with/key/{key}"
124
+ data = {"value1": msg}
125
+ return requests.post(url, data=data, timeout=(30, 30))
126
+
127
+
128
+ class IFTTTLogHandler(logging.Handler):
129
+ """
130
+ log handler for IFTTT
131
+ usage:
132
+ key = 'xxxxx.xxxzx.xxxzx.xxxzx'
133
+ iftttloghandler = IFTTTLogHandler(key, level=logging.INFO)
134
+ logging.getLogger(__name__).addHandler(iftttloghandler)
135
+ """
136
+
137
+ def __init__(self, key, level=logging.CRITICAL, *args, **kwargs):
138
+ self.key = key
139
+ super().__init__(level=level, *args, **kwargs)
140
+
141
+ def emit(self, record):
142
+ try:
143
+ send_notify(self.format(record), self.key)
144
+ except Exception as exc:
145
+ print(exc)
146
+
147
+
148
+ class SlackLogHandler(logging.Handler):
149
+ """
150
+ log handler for Slack
151
+ usage:
152
+ slackloghandler = SlackLogHandler(webhook_url, level=logging.INFO)
153
+ logging.getLogger(__name__).addHandler(slackloghandler)
154
+ """
155
+
156
+ def __init__(self, webhook_url, level=logging.CRITICAL, *args, **kwargs):
157
+ self.url = webhook_url
158
+ self.headers = {"Content-type": "application/json"}
159
+ super().__init__(level=level, *args, **kwargs)
160
+
161
+ def emit(self, record):
162
+ try:
163
+ data = {"text": self.format(record)}
164
+ requests.post(self.url, headers=self.headers, json=data, timeout=(30, 30))
165
+ except Exception as exc:
166
+ print(exc)
167
+
168
+
169
+ class DingTalkLogHandler(logging.Handler):
170
+ """
171
+ log handler for DingTalk
172
+ usage:
173
+ token = 'xxxxx.xxxzx.xxxzx.xxxzx'
174
+ dingtalkloghandler = DingTalkLogHandler(token, level=logging.INFO)
175
+ logging.getLogger(__name__).addHandler(dingtalkloghandler)
176
+ """
177
+
178
+ def __init__(self, token, level=logging.CRITICAL, *args, **kwargs):
179
+ self.token = token
180
+ super().__init__(level=level, *args, **kwargs)
181
+
182
+ def emit(self, record):
183
+ headers = {"Content-Type": "application/json"}
184
+ url = "https://oapi.dingtalk.com/robot/send"
185
+ params = {"access_token": self.token}
186
+ msg = self.format(record)
187
+ data = {"msgtype": "text", "text": {"content": msg}}
188
+ try:
189
+ response = requests.post(
190
+ url, headers=headers, params=params, json=data, timeout=(10, 10)
191
+ )
192
+ print(response.json())
193
+ except Exception as exc:
194
+ print(exc)
195
+
196
+
197
+ if __name__ == "__main__":
198
+ pass
@@ -0,0 +1 @@
1
+ from .config_loader import ConfigLoader # noqa
@@ -1,11 +1,9 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
3
  import os
4
- import sys
5
4
  import logging
6
5
 
7
6
  import yaml
8
- import requests
9
7
 
10
8
  from xenoslib.base import SingletonWithArgs
11
9
 
@@ -13,187 +11,6 @@ from xenoslib.base import SingletonWithArgs
13
11
  logger = logging.getLogger(__name__)
14
12
 
15
13
 
16
- class YamlConfig(dict):
17
- """A thread unsafe yaml file config utility , can work as a dict except __init__"""
18
-
19
- def __getattr__(self, key):
20
- return self.get(key)
21
-
22
- def __setattr__(self, name, value):
23
- try:
24
- getattr(super(), name)
25
- except AttributeError as exc:
26
- if str(exc).startswith("'super' object has no attribute "):
27
- self[name] = value
28
- return
29
- raise exc
30
- raise AttributeError(f"'{__class__.__name__}' object attribute '{name}' is read-only")
31
-
32
- def __str__(self):
33
- return yaml.safe_dump(self.copy(), allow_unicode=True)
34
-
35
- def __repr__(self):
36
- return repr(str(self))
37
-
38
- def __init__(self, conf_path=None):
39
- pass
40
-
41
- def __new__(cls, conf_path="config.yml", *args, **kwargs):
42
- if not hasattr(cls, "_instances"):
43
- cls._instances = {}
44
- if cls._instances.get(conf_path) is None:
45
- cls._instances[conf_path] = super().__new__(cls)
46
- super().__setattr__(cls._instances[conf_path], "_conf_path", conf_path)
47
- cls._instances[conf_path]._load_conf()
48
- return cls._instances[conf_path]
49
-
50
- def _load_conf(self):
51
- if os.path.exists(self._conf_path):
52
- with open(self._conf_path, encoding="utf-8") as r:
53
- self.update(yaml.safe_load(r))
54
-
55
- def save(self):
56
- data = str(self)
57
- with open(self._conf_path, "w", encoding="utf-8") as w:
58
- w.write(data)
59
- # yaml.safe_dump(self.copy(), w, allow_unicode=True)
60
-
61
-
62
- class RequestAdapter:
63
- def request(self, method, path, *args, **kwargs):
64
- """to-do: support stream=True"""
65
- url = f"{self.base_url}/{path}"
66
- logger.debug(url)
67
- response = self.session.request(method, url, *args, **kwargs)
68
- logger.debug(response.text)
69
- response.raise_for_status()
70
- try:
71
- return response.json()
72
- except Exception as exc:
73
- logger.debug(exc)
74
- return response
75
-
76
- def get(self, path, *args, **kwargs):
77
- return self.request("get", path, *args, **kwargs)
78
-
79
- def post(self, path, *args, **kwargs):
80
- return self.request("post", path, *args, **kwargs)
81
-
82
- def put(self, path, *args, **kwargs):
83
- return self.request("put", path, *args, **kwargs)
84
-
85
- def delete(self, path, *args, **kwargs):
86
- return self.request("delete", path, *args, **kwargs)
87
-
88
- def patch(self, path, *args, **kwargs):
89
- return self.request("patch", path, *args, **kwargs)
90
-
91
- def head(self, path, *args, **kwargs):
92
- return self.request("head", path, *args, **kwargs)
93
-
94
- def __init__(self):
95
- self.session = requests.Session()
96
-
97
-
98
- def del_to_recyclebin(filepath, on_fail_delete=False):
99
- """delete file to recyclebin if possible"""
100
- if not sys.platform == "win32":
101
- if on_fail_delete:
102
- os.remove(filepath)
103
- return True
104
- return False
105
- from win32com.shell import shell, shellcon
106
-
107
- res, _ = shell.SHFileOperation(
108
- (
109
- 0,
110
- shellcon.FO_DELETE,
111
- filepath,
112
- None,
113
- shellcon.FOF_SILENT | shellcon.FOF_ALLOWUNDO | shellcon.FOF_NOCONFIRMATION,
114
- None,
115
- None,
116
- )
117
- )
118
- return res == 0
119
-
120
-
121
- def send_notify(msg, key):
122
- """send a message for ifttt"""
123
- url = f"https://maker.ifttt.com/trigger/message/with/key/{key}"
124
- data = {"value1": msg}
125
- return requests.post(url, data=data, timeout=(30, 30))
126
-
127
-
128
- class IFTTTLogHandler(logging.Handler):
129
- """
130
- log handler for IFTTT
131
- usage:
132
- key = 'xxxxx.xxxzx.xxxzx.xxxzx'
133
- iftttloghandler = IFTTTLogHandler(key, level=logging.INFO)
134
- logging.getLogger(__name__).addHandler(iftttloghandler)
135
- """
136
-
137
- def __init__(self, key, level=logging.CRITICAL, *args, **kwargs):
138
- self.key = key
139
- super().__init__(level=level, *args, **kwargs)
140
-
141
- def emit(self, record):
142
- try:
143
- send_notify(self.format(record), self.key)
144
- except Exception as exc:
145
- print(exc)
146
-
147
-
148
- class SlackLogHandler(logging.Handler):
149
- """
150
- log handler for Slack
151
- usage:
152
- slackloghandler = SlackLogHandler(webhook_url, level=logging.INFO)
153
- logging.getLogger(__name__).addHandler(slackloghandler)
154
- """
155
-
156
- def __init__(self, webhook_url, level=logging.CRITICAL, *args, **kwargs):
157
- self.url = webhook_url
158
- self.headers = {"Content-type": "application/json"}
159
- super().__init__(level=level, *args, **kwargs)
160
-
161
- def emit(self, record):
162
- try:
163
- data = {"text": self.format(record)}
164
- requests.post(self.url, headers=self.headers, json=data, timeout=(30, 30))
165
- except Exception as exc:
166
- print(exc)
167
-
168
-
169
- class DingTalkLogHandler(logging.Handler):
170
- """
171
- log handler for DingTalk
172
- usage:
173
- token = 'xxxxx.xxxzx.xxxzx.xxxzx'
174
- dingtalkloghandler = DingTalkLogHandler(token, level=logging.INFO)
175
- logging.getLogger(__name__).addHandler(dingtalkloghandler)
176
- """
177
-
178
- def __init__(self, token, level=logging.CRITICAL, *args, **kwargs):
179
- self.token = token
180
- super().__init__(level=level, *args, **kwargs)
181
-
182
- def emit(self, record):
183
- headers = {"Content-Type": "application/json"}
184
- url = "https://oapi.dingtalk.com/robot/send"
185
- params = {"access_token": self.token}
186
- msg = self.format(record)
187
- data = {"msgtype": "text", "text": {"content": msg}}
188
- try:
189
- response = requests.post(
190
- url, headers=headers, params=params, json=data, timeout=(10, 10)
191
- )
192
- print(response.json())
193
- except Exception as exc:
194
- print(exc)
195
-
196
-
197
14
  class ConfigLoader(SingletonWithArgs):
198
15
  """Centralized configuration management with optional Vault integration.
199
16
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xenoslib
3
- Version: 0.1.29.24
3
+ Version: 0.1.30
4
4
  Summary: Xenos' common lib
5
5
  Home-page: https://github.com/XenosLu/xenoslib.git
6
6
  Author: Xenocider
@@ -17,4 +17,6 @@ xenoslib.egg-info/PKG-INFO
17
17
  xenoslib.egg-info/SOURCES.txt
18
18
  xenoslib.egg-info/dependency_links.txt
19
19
  xenoslib.egg-info/requires.txt
20
- xenoslib.egg-info/top_level.txt
20
+ xenoslib.egg-info/top_level.txt
21
+ xenoslib/tools/__init__.py
22
+ xenoslib/tools/config_loader.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes