cobweb-launcher 1.2.25__tar.gz → 1.2.27__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.

Potentially problematic release.


This version of cobweb-launcher might be problematic. Click here for more details.

Files changed (78) hide show
  1. {cobweb-launcher-1.2.25/cobweb_launcher.egg-info → cobweb-launcher-1.2.27}/PKG-INFO +1 -1
  2. cobweb-launcher-1.2.27/cobweb/crawlers/crawler.py +183 -0
  3. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/launchers/launcher.py +3 -0
  4. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/utils/__init__.py +1 -0
  5. cobweb-launcher-1.2.27/cobweb/utils/dotting.py +28 -0
  6. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27/cobweb_launcher.egg-info}/PKG-INFO +1 -1
  7. cobweb-launcher-1.2.27/cobweb_launcher.egg-info/SOURCES.txt +74 -0
  8. cobweb-launcher-1.2.27/cobweb_launcher.egg-info/top_level.txt +2 -0
  9. cobweb-launcher-1.2.27/cobweb_new/__init__.py +2 -0
  10. cobweb-launcher-1.2.27/cobweb_new/base/__init__.py +72 -0
  11. cobweb-launcher-1.2.27/cobweb_new/base/common_queue.py +53 -0
  12. cobweb-launcher-1.2.27/cobweb_new/base/decorators.py +72 -0
  13. cobweb-launcher-1.2.27/cobweb_new/base/item.py +46 -0
  14. cobweb-launcher-1.2.27/cobweb_new/base/log.py +94 -0
  15. cobweb-launcher-1.2.27/cobweb_new/base/request.py +82 -0
  16. cobweb-launcher-1.2.27/cobweb_new/base/response.py +23 -0
  17. cobweb-launcher-1.2.27/cobweb_new/base/seed.py +118 -0
  18. cobweb-launcher-1.2.27/cobweb_new/constant.py +105 -0
  19. cobweb-launcher-1.2.27/cobweb_new/crawlers/__init__.py +1 -0
  20. cobweb-launcher-1.2.27/cobweb_new/crawlers/crawler-new.py +85 -0
  21. cobweb-launcher-1.2.27/cobweb_new/db/__init__.py +2 -0
  22. cobweb-launcher-1.2.27/cobweb_new/db/api_db.py +82 -0
  23. cobweb-launcher-1.2.27/cobweb_new/db/redis_db.py +158 -0
  24. cobweb-launcher-1.2.27/cobweb_new/exceptions/__init__.py +1 -0
  25. cobweb-launcher-1.2.27/cobweb_new/exceptions/oss_db_exception.py +28 -0
  26. cobweb-launcher-1.2.27/cobweb_new/launchers/__init__.py +3 -0
  27. cobweb-launcher-1.2.27/cobweb_new/launchers/launcher.py +237 -0
  28. cobweb-launcher-1.2.27/cobweb_new/launchers/launcher_air.py +88 -0
  29. cobweb-launcher-1.2.27/cobweb_new/launchers/launcher_api.py +161 -0
  30. cobweb-launcher-1.2.27/cobweb_new/launchers/launcher_pro.py +96 -0
  31. cobweb-launcher-1.2.27/cobweb_new/launchers/tesss.py +47 -0
  32. cobweb-launcher-1.2.27/cobweb_new/pipelines/__init__.py +3 -0
  33. cobweb-launcher-1.2.27/cobweb_new/pipelines/pipeline.py +68 -0
  34. cobweb-launcher-1.2.27/cobweb_new/pipelines/pipeline_console.py +22 -0
  35. cobweb-launcher-1.2.27/cobweb_new/pipelines/pipeline_loghub.py +34 -0
  36. cobweb-launcher-1.2.27/cobweb_new/setting.py +95 -0
  37. cobweb-launcher-1.2.27/cobweb_new/utils/__init__.py +5 -0
  38. cobweb-launcher-1.2.27/cobweb_new/utils/bloom.py +58 -0
  39. cobweb-launcher-1.2.27/cobweb_new/utils/oss.py +94 -0
  40. cobweb-launcher-1.2.27/cobweb_new/utils/tools.py +42 -0
  41. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/setup.py +1 -1
  42. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/test/test.py +1 -10
  43. cobweb-launcher-1.2.25/cobweb_launcher.egg-info/SOURCES.txt +0 -40
  44. cobweb-launcher-1.2.25/cobweb_launcher.egg-info/top_level.txt +0 -1
  45. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/LICENSE +0 -0
  46. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/README.md +0 -0
  47. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/__init__.py +0 -0
  48. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/base/__init__.py +0 -0
  49. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/base/common_queue.py +0 -0
  50. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/base/decorators.py +0 -0
  51. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/base/item.py +0 -0
  52. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/base/log.py +0 -0
  53. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/base/request.py +0 -0
  54. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/base/response.py +0 -0
  55. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/base/seed.py +0 -0
  56. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/constant.py +0 -0
  57. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/crawlers/__init__.py +0 -0
  58. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/db/__init__.py +0 -0
  59. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/db/api_db.py +0 -0
  60. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/db/redis_db.py +0 -0
  61. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/exceptions/__init__.py +0 -0
  62. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/exceptions/oss_db_exception.py +0 -0
  63. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/launchers/__init__.py +0 -0
  64. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/launchers/launcher_air.py +0 -0
  65. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/launchers/launcher_api.py +0 -0
  66. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/launchers/launcher_pro.py +0 -0
  67. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/pipelines/__init__.py +0 -0
  68. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/pipelines/pipeline.py +0 -0
  69. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/pipelines/pipeline_console.py +0 -0
  70. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/pipelines/pipeline_loghub.py +0 -0
  71. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/setting.py +0 -0
  72. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/utils/bloom.py +0 -0
  73. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/utils/oss.py +0 -0
  74. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb/utils/tools.py +0 -0
  75. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb_launcher.egg-info/dependency_links.txt +0 -0
  76. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/cobweb_launcher.egg-info/requires.txt +0 -0
  77. {cobweb-launcher-1.2.25/cobweb → cobweb-launcher-1.2.27/cobweb_new}/crawlers/crawler.py +0 -0
  78. {cobweb-launcher-1.2.25 → cobweb-launcher-1.2.27}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cobweb-launcher
3
- Version: 1.2.25
3
+ Version: 1.2.27
4
4
  Summary: spider_hole
5
5
  Home-page: https://github.com/Juannie-PP/cobweb
6
6
  Author: Juannie-PP
@@ -0,0 +1,183 @@
1
+ import json
2
+ import threading
3
+ import time
4
+ import traceback
5
+ from inspect import isgenerator
6
+ from typing import Union, Callable, Mapping
7
+
8
+ from cobweb.constant import DealModel, LogTemplate
9
+ from cobweb.base import (
10
+ Queue,
11
+ Seed,
12
+ BaseItem,
13
+ Request,
14
+ Response,
15
+ ConsoleItem,
16
+ logger
17
+ )
18
+ from cobweb.utils import LoghubDot
19
+
20
+
21
+ class Crawler(threading.Thread):
22
+
23
+ def __init__(
24
+ self,
25
+ task: str,
26
+ project: str,
27
+ stop: threading.Event,
28
+ pause: threading.Event,
29
+ # launcher_queue: Union[Mapping[str, Queue]],
30
+ get_seed: Callable,
31
+ set_seed: Callable,
32
+ add_seed: Callable,
33
+ delete_seed: Callable,
34
+ upload_data: Callable,
35
+ custom_func: Union[Mapping[str, Callable]],
36
+ thread_num: int,
37
+ max_retries: int,
38
+ time_sleep: int,
39
+ ):
40
+ super().__init__()
41
+ self.task = task
42
+ self.project = project
43
+ self._stop = stop
44
+ self._pause = pause
45
+ self._get_seed = get_seed
46
+ self._set_seed = set_seed
47
+ self._add_seed = add_seed
48
+ self._delete_seed = delete_seed
49
+ self._upload_data = upload_data
50
+
51
+ for func_name, _callable in custom_func.items():
52
+ if isinstance(_callable, Callable):
53
+ self.__setattr__(func_name, _callable)
54
+
55
+ self.thread_num = thread_num
56
+ self.time_sleep = time_sleep
57
+ self.max_retries = max_retries
58
+
59
+ self.loghub_dot = LoghubDot()
60
+
61
+ @staticmethod
62
+ def request(seed: Seed) -> Union[Request, BaseItem]:
63
+ yield Request(seed.url, seed, timeout=5)
64
+
65
+ @staticmethod
66
+ def download(item: Request) -> Union[Seed, BaseItem, Response, str]:
67
+ response = item.download()
68
+ yield Response(item.seed, response, **item.to_dict)
69
+
70
+ @staticmethod
71
+ def parse(item: Response) -> BaseItem:
72
+ upload_item = item.to_dict
73
+ upload_item["text"] = item.response.text
74
+ yield ConsoleItem(item.seed, data=json.dumps(upload_item, ensure_ascii=False))
75
+
76
+ # def get_seed(self) -> Seed:
77
+ # return self._todo.pop()
78
+
79
+ def distribute(self, item, seed):
80
+ if isinstance(item, BaseItem):
81
+ self._upload_data(item)
82
+ elif isinstance(item, Seed):
83
+ self._add_seed(item)
84
+ elif isinstance(item, str) and item == DealModel.poll:
85
+ self._set_seed(seed)
86
+ elif isinstance(item, str) and item == DealModel.done:
87
+ self._delete_seed(seed)
88
+ elif isinstance(item, str) and item == DealModel.fail:
89
+ seed.params.seed_status = DealModel.fail
90
+ self._delete_seed(seed)
91
+ else:
92
+ raise TypeError("yield value type error!")
93
+
94
+ def spider(self):
95
+ while not self._stop.is_set():
96
+
97
+ seed = self._get_seed()
98
+
99
+ if not seed:
100
+ time.sleep(1)
101
+ continue
102
+
103
+ elif seed.params.retry > self.max_retries:
104
+ seed.params.seed_status = DealModel.fail
105
+ self._delete_seed(seed)
106
+ continue
107
+
108
+ seed_detail_log_info = LogTemplate.log_info(seed.to_dict)
109
+
110
+ try:
111
+ request_iterators = self.request(seed)
112
+
113
+ if not isgenerator(request_iterators):
114
+ raise TypeError("request function isn't a generator!")
115
+
116
+ iterator_status = False
117
+
118
+ for request_item in request_iterators:
119
+
120
+ iterator_status = True
121
+
122
+ if isinstance(request_item, Request):
123
+ iterator_status = False
124
+ start_time = time.time()
125
+ download_iterators = self.download(request_item)
126
+ if not isgenerator(download_iterators):
127
+ raise TypeError("download function isn't a generator")
128
+
129
+ for download_item in download_iterators:
130
+ iterator_status = True
131
+ if isinstance(download_item, Response):
132
+ iterator_status = False
133
+ logger.info(LogTemplate.download_info.format(
134
+ detail=seed_detail_log_info,
135
+ retry=seed.params.retry,
136
+ priority=seed.params.priority,
137
+ seed_version=seed.params.seed_version,
138
+ identifier=seed.identifier or "",
139
+ status=download_item.response,
140
+ response=LogTemplate.log_info(download_item.to_dict)
141
+ ))
142
+ if isinstance(download_item, Response):
143
+ end_time = time.time()
144
+ self.loghub_dot.build(topic=f"{self.project}:{self.task}", data={
145
+ "cost_time": end_time - start_time,
146
+ **download_item.to_dict
147
+ })
148
+ parse_iterators = self.parse(download_item)
149
+ if not isgenerator(parse_iterators):
150
+ raise TypeError("parse function isn't a generator")
151
+ for parse_item in parse_iterators:
152
+ iterator_status = True
153
+ if isinstance(parse_item, Response):
154
+ raise TypeError("upload_item can't be a Response instance")
155
+ self.distribute(parse_item, seed)
156
+ else:
157
+ self.distribute(download_item, seed)
158
+ else:
159
+ self.distribute(request_item, seed)
160
+
161
+ if not iterator_status:
162
+ raise ValueError("request/download/parse function yield value error!")
163
+ except Exception as e:
164
+ logger.info(LogTemplate.download_exception.format(
165
+ detail=seed_detail_log_info,
166
+ retry=seed.params.retry,
167
+ priority=seed.params.priority,
168
+ seed_version=seed.params.seed_version,
169
+ identifier=seed.identifier or "",
170
+ exception=''.join(traceback.format_exception(type(e), e, e.__traceback__))
171
+ ))
172
+ seed.params.retry += 1
173
+ # self._todo.push(seed)
174
+ self._set_seed(seed)
175
+ time.sleep(self.time_sleep * seed.params.retry)
176
+ finally:
177
+ time.sleep(0.1)
178
+ logger.info("spider thread close")
179
+
180
+ def run(self):
181
+ for index in range(self.thread_num):
182
+ threading.Thread(name=f"spider_{index}", target=self.spider).start()
183
+
@@ -4,6 +4,8 @@ import threading
4
4
  import importlib
5
5
  from functools import wraps
6
6
 
7
+ from mypyc.doc.conf import project
8
+
7
9
  from cobweb import setting
8
10
  from cobweb.base import Seed, Queue, logger
9
11
  from cobweb.utils.tools import dynamic_load_class
@@ -186,6 +188,7 @@ class Launcher(threading.Thread):
186
188
  self.start_seeds()
187
189
 
188
190
  self._Crawler(
191
+ task=self.task, project=self.project,
189
192
  stop=self._stop, pause=self._pause,
190
193
  # launcher_queue=self.__LAUNCHER_QUEUE__,
191
194
  get_seed=self._get_seed,
@@ -1,4 +1,5 @@
1
1
  from .oss import OssUtil
2
2
  from .tools import *
3
3
  from .bloom import BloomFilter
4
+ from .dotting import LoghubDot
4
5
 
@@ -0,0 +1,28 @@
1
+ import json
2
+
3
+ from aliyun.log import LogClient, PutLogsRequest, LogItem
4
+
5
+ import setting
6
+
7
+
8
+ class LoghubDot:
9
+
10
+ def __init__(self, *args, **kwargs):
11
+ super().__init__(*args, **kwargs)
12
+ self.client = LogClient(**setting.LOGHUB_CONFIG)
13
+
14
+ def build(self, topic, data):
15
+ log_item = LogItem()
16
+ for key, value in data.items():
17
+ if not isinstance(value, str):
18
+ data[key] = json.dumps(value, ensure_ascii=False)
19
+ contents = sorted(data.items())
20
+ log_item.set_contents(contents)
21
+ request = PutLogsRequest(
22
+ project=setting.LOGHUB_PROJECT,
23
+ logstore="cobweb_log",
24
+ topic=topic,
25
+ logitems=contents,
26
+ compress=True
27
+ )
28
+ self.client.put_logs(request=request)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cobweb-launcher
3
- Version: 1.2.25
3
+ Version: 1.2.27
4
4
  Summary: spider_hole
5
5
  Home-page: https://github.com/Juannie-PP/cobweb
6
6
  Author: Juannie-PP
@@ -0,0 +1,74 @@
1
+ LICENSE
2
+ README.md
3
+ setup.py
4
+ cobweb/__init__.py
5
+ cobweb/constant.py
6
+ cobweb/setting.py
7
+ cobweb/base/__init__.py
8
+ cobweb/base/common_queue.py
9
+ cobweb/base/decorators.py
10
+ cobweb/base/item.py
11
+ cobweb/base/log.py
12
+ cobweb/base/request.py
13
+ cobweb/base/response.py
14
+ cobweb/base/seed.py
15
+ cobweb/crawlers/__init__.py
16
+ cobweb/crawlers/crawler.py
17
+ cobweb/db/__init__.py
18
+ cobweb/db/api_db.py
19
+ cobweb/db/redis_db.py
20
+ cobweb/exceptions/__init__.py
21
+ cobweb/exceptions/oss_db_exception.py
22
+ cobweb/launchers/__init__.py
23
+ cobweb/launchers/launcher.py
24
+ cobweb/launchers/launcher_air.py
25
+ cobweb/launchers/launcher_api.py
26
+ cobweb/launchers/launcher_pro.py
27
+ cobweb/pipelines/__init__.py
28
+ cobweb/pipelines/pipeline.py
29
+ cobweb/pipelines/pipeline_console.py
30
+ cobweb/pipelines/pipeline_loghub.py
31
+ cobweb/utils/__init__.py
32
+ cobweb/utils/bloom.py
33
+ cobweb/utils/dotting.py
34
+ cobweb/utils/oss.py
35
+ cobweb/utils/tools.py
36
+ cobweb_launcher.egg-info/PKG-INFO
37
+ cobweb_launcher.egg-info/SOURCES.txt
38
+ cobweb_launcher.egg-info/dependency_links.txt
39
+ cobweb_launcher.egg-info/requires.txt
40
+ cobweb_launcher.egg-info/top_level.txt
41
+ cobweb_new/__init__.py
42
+ cobweb_new/constant.py
43
+ cobweb_new/setting.py
44
+ cobweb_new/base/__init__.py
45
+ cobweb_new/base/common_queue.py
46
+ cobweb_new/base/decorators.py
47
+ cobweb_new/base/item.py
48
+ cobweb_new/base/log.py
49
+ cobweb_new/base/request.py
50
+ cobweb_new/base/response.py
51
+ cobweb_new/base/seed.py
52
+ cobweb_new/crawlers/__init__.py
53
+ cobweb_new/crawlers/crawler-new.py
54
+ cobweb_new/crawlers/crawler.py
55
+ cobweb_new/db/__init__.py
56
+ cobweb_new/db/api_db.py
57
+ cobweb_new/db/redis_db.py
58
+ cobweb_new/exceptions/__init__.py
59
+ cobweb_new/exceptions/oss_db_exception.py
60
+ cobweb_new/launchers/__init__.py
61
+ cobweb_new/launchers/launcher.py
62
+ cobweb_new/launchers/launcher_air.py
63
+ cobweb_new/launchers/launcher_api.py
64
+ cobweb_new/launchers/launcher_pro.py
65
+ cobweb_new/launchers/tesss.py
66
+ cobweb_new/pipelines/__init__.py
67
+ cobweb_new/pipelines/pipeline.py
68
+ cobweb_new/pipelines/pipeline_console.py
69
+ cobweb_new/pipelines/pipeline_loghub.py
70
+ cobweb_new/utils/__init__.py
71
+ cobweb_new/utils/bloom.py
72
+ cobweb_new/utils/oss.py
73
+ cobweb_new/utils/tools.py
74
+ test/test.py
@@ -0,0 +1,2 @@
1
+ cobweb
2
+ cobweb_new
@@ -0,0 +1,2 @@
1
+ from .launchers import LauncherAir, LauncherPro, LauncherApi
2
+ from .constant import CrawlerModel
@@ -0,0 +1,72 @@
1
+ import time
2
+ from inspect import isgenerator
3
+ from typing import Callable, Union
4
+
5
+ from .common_queue import Queue
6
+ from .response import Response
7
+ from .request import Request
8
+ from .item import BaseItem, ConsoleItem
9
+ from .seed import Seed
10
+
11
+ from .log import logger
12
+ # from .decorators import decorator_oss_db, stop, pause
13
+ import decorators
14
+
15
+
16
+ class TaskQueue:
17
+
18
+ SEED = Queue() # 添加任务种子队列
19
+ TODO = Queue() # 任务种子队列
20
+ REQUEST = Queue() # 请求队列
21
+
22
+ DOWNLOAD = Queue() # 下载任务队列
23
+ RESPONSE = Queue() # 响应队列
24
+ DONE = Queue() # 下载完成队列
25
+
26
+ UPLOAD = Queue() # 任务上传队列
27
+
28
+ DELETE = Queue() # 任务删除队列
29
+
30
+ def __init__(self, db):
31
+ self.db = db
32
+
33
+ @staticmethod
34
+ def is_empty():
35
+ total_length = TaskQueue.SEED.length
36
+ total_length += TaskQueue.TODO.length
37
+ total_length += TaskQueue.REQUEST.length
38
+ total_length += TaskQueue.DOWNLOAD.length
39
+ total_length += TaskQueue.RESPONSE.length
40
+ total_length += TaskQueue.UPLOAD.length
41
+ total_length += TaskQueue.DONE.length
42
+ total_length += TaskQueue.DELETE.length
43
+ return not bool(total_length)
44
+ # @staticmethod
45
+ # def distribute(it):
46
+
47
+ @staticmethod
48
+ def process_task(it: Union[Seed, Request, Response, BaseItem], crawler_func: Callable):
49
+ try:
50
+ iterators = crawler_func(it)
51
+ if not isgenerator(iterators):
52
+ raise TypeError(f"{crawler_func.__name__} function isn't a generator")
53
+ for tk in iterators:
54
+ if isinstance(tk, Request):
55
+ TaskQueue.DOWNLOAD.push(tk)
56
+ elif isinstance(tk, Response):
57
+ TaskQueue.RESPONSE.push(tk)
58
+ elif isinstance(tk, BaseItem):
59
+ TaskQueue.UPLOAD.push(tk)
60
+ elif isinstance(tk, Seed):
61
+ TaskQueue.SEED.push(tk)
62
+ except Exception as e:
63
+ if not isinstance(it, BaseItem):
64
+ it.seed.params.retry += 1
65
+
66
+ time.sleep(5)
67
+
68
+
69
+ class Distribute:
70
+ """
71
+ 数据分发器,将数据分发到各个队列中
72
+ """
@@ -0,0 +1,53 @@
1
+ import time
2
+ from collections import deque
3
+
4
+
5
+ class Queue:
6
+
7
+ def __init__(self):
8
+ self._queue = deque()
9
+
10
+ @property
11
+ def length(self) -> int:
12
+ return len(self._queue)
13
+
14
+ def push(self, data, left: bool = False, direct_insertion: bool = False):
15
+ try:
16
+ if not data:
17
+ return None
18
+ if not direct_insertion and any(isinstance(data, t) for t in (list, tuple)):
19
+ self._queue.extendleft(data) if left else self._queue.extend(data)
20
+ else:
21
+ self._queue.appendleft(data) if left else self._queue.append(data)
22
+ except AttributeError:
23
+ pass
24
+
25
+ def pop(self, left: bool = True):
26
+ try:
27
+ return self._queue.popleft() if left else self._queue.pop()
28
+ except IndexError:
29
+ return None
30
+ except AttributeError:
31
+ return None
32
+
33
+ def clear(self):
34
+ self._queue.clear()
35
+
36
+ def get(self):
37
+ try:
38
+ yield self._queue.popleft()
39
+ except IndexError:
40
+ time.sleep(1)
41
+ yield None
42
+ except AttributeError:
43
+ yield None
44
+
45
+
46
+ class RedisQueue(Queue):
47
+
48
+ def __init__(self, db):
49
+ super().__init__()
50
+ self.db = db
51
+
52
+ def pop(self, left: bool = True):
53
+ ...
@@ -0,0 +1,72 @@
1
+ import time
2
+ import threading
3
+ from functools import wraps
4
+
5
+
6
+ def add_thread(num=1):
7
+ def decorator(func):
8
+ @wraps(func)
9
+ def wrapper(self, *args):
10
+ for i in range(num):
11
+ name = func.__name__ + "_" + str(i) if num > 1 else func.__name__
12
+ self._threads.append(threading.Thread(name=name, target=func, args=(self,) + args))
13
+ return wrapper
14
+
15
+ return decorator
16
+
17
+
18
+ def pause(func):
19
+ @wraps(func)
20
+ def wrapper(self, *args, **kwargs):
21
+ while not self.pause.is_set():
22
+ try:
23
+ func(self, *args, **kwargs)
24
+ except Exception as e:
25
+ pass
26
+ # logger.info(f"{func.__name__}: " + str(e))
27
+ finally:
28
+ time.sleep(0.1)
29
+
30
+ return wrapper
31
+
32
+
33
+ def stop(func):
34
+ @wraps(func)
35
+ def wrapper(self, *args, **kwargs):
36
+ while not self.stop.is_set():
37
+ try:
38
+ func(self, *args, **kwargs)
39
+ except Exception as e:
40
+ # logger.info(f"{func.__name__}: " + str(e))
41
+ pass
42
+ finally:
43
+ time.sleep(0.1)
44
+
45
+ return wrapper
46
+
47
+
48
+ def decorator_oss_db(exception, retries=3):
49
+ def decorator(func):
50
+ @wraps(func)
51
+ def wrapper(callback_func, *args, **kwargs):
52
+ result = None
53
+ for i in range(retries):
54
+ msg = None
55
+ try:
56
+ return func(callback_func, *args, **kwargs)
57
+ except Exception as e:
58
+ result = None
59
+ msg = e
60
+ finally:
61
+ if result:
62
+ return result
63
+
64
+ if i >= 2 and msg:
65
+ raise exception(msg)
66
+
67
+ return wrapper
68
+
69
+ return decorator
70
+
71
+
72
+
@@ -0,0 +1,46 @@
1
+ from .seed import Seed
2
+ from collections import namedtuple
3
+
4
+
5
+ class Item(type):
6
+
7
+ def __new__(cls, name, bases, dct):
8
+ new_class_instance = type.__new__(cls, name, bases, dct)
9
+ if name != "BaseItem":
10
+ table = getattr(new_class_instance, "__TABLE__")
11
+ fields = getattr(new_class_instance, "__FIELDS__")
12
+ new_class_instance.Data = namedtuple(table, fields)
13
+ return new_class_instance
14
+
15
+
16
+ class BaseItem(metaclass=Item):
17
+
18
+ __TABLE__ = ""
19
+ __FIELDS__ = ""
20
+
21
+ def __init__(self, seed: Seed, **kwargs):
22
+ self.seed = seed
23
+
24
+ data = {}
25
+ for key, value in kwargs.items():
26
+ if key not in self.__FIELDS__:
27
+ self.__setattr__(key, value)
28
+ else:
29
+ data[key] = value
30
+
31
+ self.data = self.Data(**data)
32
+
33
+ @property
34
+ def to_dict(self):
35
+ return self.data._asdict()
36
+
37
+ @property
38
+ def table(self):
39
+ return self.Data.__name__
40
+
41
+
42
+ class ConsoleItem(BaseItem):
43
+
44
+ __TABLE__ = "console"
45
+ __FIELDS__ = "data"
46
+
@@ -0,0 +1,94 @@
1
+ import logging
2
+
3
+
4
+ class ColorCodes:
5
+ # Text Reset
6
+ RESET = "\033[0m"
7
+
8
+ # Regular Colors
9
+ RED = "\033[31m"
10
+ GREEN = "\033[32m"
11
+ YELLOW = "\033[33m"
12
+ BLUE = "\033[34m"
13
+ PURPLE = "\033[35m"
14
+ CYAN = "\033[36m"
15
+ WHITE = "\033[37m"
16
+
17
+ # Bright Colors
18
+ BRIGHT_RED = "\033[91m"
19
+ BRIGHT_GREEN = "\033[92m"
20
+ BRIGHT_YELLOW = "\033[93m"
21
+ BRIGHT_BLUE = "\033[94m"
22
+ BRIGHT_PURPLE = "\033[95m"
23
+ BRIGHT_CYAN = "\033[96m"
24
+ BRIGHT_WHITE = "\033[97m"
25
+
26
+ # Background Colors
27
+ BG_RED = "\033[41m"
28
+ BG_GREEN = "\033[42m"
29
+ BG_YELLOW = "\033[43m"
30
+ BG_BLUE = "\033[44m"
31
+ BG_PURPLE = "\033[45m"
32
+ BG_CYAN = "\033[46m"
33
+ BG_WHITE = "\033[47m"
34
+
35
+ # Bright Background Colors
36
+ BG_BRIGHT_RED = "\033[101m"
37
+ BG_BRIGHT_GREEN = "\033[102m"
38
+ BG_BRIGHT_YELLOW = "\033[103m"
39
+ BG_BRIGHT_BLUE = "\033[104m"
40
+ BG_BRIGHT_PURPLE = "\033[105m"
41
+ BG_BRIGHT_CYAN = "\033[106m"
42
+ BG_BRIGHT_WHITE = "\033[107m"
43
+
44
+ # Text Styles
45
+ BOLD = "\033[1m"
46
+ DIM = "\033[2m"
47
+ ITALIC = "\033[3m"
48
+ UNDERLINE = "\033[4m"
49
+ BLINK = "\033[5m"
50
+ REVERSE = "\033[7m"
51
+ HIDDEN = "\033[8m"
52
+
53
+
54
+ class Log:
55
+ logging.getLogger('oss2.api').setLevel(logging.WARNING)
56
+ logging.basicConfig(
57
+ level=logging.INFO,
58
+ format=f'%(asctime)s %(name)s [%(filename)s:%(lineno)d %(funcName)s]'
59
+ f' %(levelname)s -> %(message)s'
60
+ )
61
+ log = logging.getLogger()
62
+
63
+ def set_log_name(self, name):
64
+ self.__class__.log = logging.getLogger(name)
65
+
66
+ @property
67
+ def debug(self):
68
+ return self.__class__.log.debug
69
+
70
+ @property
71
+ def info(self):
72
+ return self.__class__.log.info
73
+
74
+ @property
75
+ def warning(self):
76
+ return self.__class__.log.warning
77
+
78
+ @property
79
+ def exception(self):
80
+ return self.__class__.log.exception
81
+
82
+ @property
83
+ def error(self):
84
+ return self.__class__.log.error
85
+
86
+ @property
87
+ def critical(self):
88
+ return self.__class__.log.critical
89
+
90
+
91
+ logger = Log()
92
+
93
+
94
+