valar 1.1.4__tar.gz → 1.2.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.

Potentially problematic release.


This version of valar might be problematic. Click here for more details.

Files changed (64) hide show
  1. {valar-1.1.4/src/valar.egg-info → valar-1.2.1}/PKG-INFO +9 -14
  2. {valar-1.1.4 → valar-1.2.1}/README.md +8 -13
  3. {valar-1.1.4 → valar-1.2.1}/setup.py +4 -4
  4. valar-1.2.1/src/valar/apps.py +18 -0
  5. {valar-1.1.4 → valar-1.2.1}/src/valar/channels/consumer.py +10 -12
  6. valar-1.2.1/src/valar/channels/executer.py +14 -0
  7. valar-1.2.1/src/valar/channels/sender.py +116 -0
  8. {valar-1.1.4 → valar-1.2.1}/src/valar/channels/views.py +2 -3
  9. {valar-1.1.4/src/valar/classes → valar-1.2.1/src/valar/classes/app_mixins}/auto_migration_mixin.py +2 -2
  10. {valar-1.1.4/src/valar/classes → valar-1.2.1/src/valar/classes/app_mixins}/auto_urlpatterns_mixin.py +3 -3
  11. valar-1.2.1/src/valar/classes/valar_minio.py +80 -0
  12. {valar-1.1.4 → valar-1.2.1}/src/valar/classes/valar_response.py +2 -1
  13. valar-1.2.1/src/valar/dao/__init__.py +45 -0
  14. valar-1.2.1/src/valar/dao/abstract.py +106 -0
  15. valar-1.2.1/src/valar/dao/defaults/field_keys_default.py +48 -0
  16. valar-1.2.1/src/valar/dao/defaults/field_values_default.py +135 -0
  17. valar-1.2.1/src/valar/dao/defaults/view_defaults.py +26 -0
  18. valar-1.2.1/src/valar/dao/engine.py +80 -0
  19. valar-1.2.1/src/valar/dao/frame.py +189 -0
  20. valar-1.2.1/src/valar/dao/meta.py +128 -0
  21. valar-1.2.1/src/valar/dao/mon_dao.py +113 -0
  22. valar-1.2.1/src/valar/dao/mon_field.py +23 -0
  23. valar-1.2.1/src/valar/dao/orm_dao.py +304 -0
  24. valar-1.2.1/src/valar/dao/orm_field.py +142 -0
  25. valar-1.2.1/src/valar/dao/query.py +36 -0
  26. {valar-1.1.4 → valar-1.2.1}/src/valar/migrations/0001_initial.py +25 -17
  27. {valar-1.1.4 → valar-1.2.1}/src/valar/models/core.py +16 -10
  28. {valar-1.1.4 → valar-1.2.1}/src/valar/models/frame.py +4 -7
  29. {valar-1.1.4 → valar-1.2.1}/src/valar/models/meta.py +19 -16
  30. valar-1.2.1/src/valar/urls.py +29 -0
  31. valar-1.2.1/src/valar/views/__init__.py +0 -0
  32. valar-1.2.1/src/valar/views/file.py +49 -0
  33. valar-1.2.1/src/valar/views/handler.py +33 -0
  34. valar-1.2.1/src/valar/views/meta.py +150 -0
  35. valar-1.2.1/src/valar/views/rest.py +90 -0
  36. {valar-1.1.4 → valar-1.2.1/src/valar.egg-info}/PKG-INFO +9 -14
  37. valar-1.2.1/src/valar.egg-info/SOURCES.txt +57 -0
  38. {valar-1.1.4 → valar-1.2.1}/src/valar.egg-info/top_level.txt +1 -0
  39. valar-1.2.1/src/vtest/__init__.py +0 -0
  40. valar-1.2.1/src/vtest/apps.py +17 -0
  41. valar-1.2.1/src/vtest/handlers.py +15 -0
  42. valar-1.2.1/src/vtest/migrations/0001_initial.py +155 -0
  43. valar-1.2.1/src/vtest/migrations/__init__.py +0 -0
  44. valar-1.2.1/src/vtest/models.py +59 -0
  45. valar-1.2.1/src/vtest/views.py +8 -0
  46. valar-1.1.4/src/valar/apps.py +0 -21
  47. valar-1.1.4/src/valar/channels/executer.py +0 -13
  48. valar-1.1.4/src/valar/channels/sender.py +0 -64
  49. valar-1.1.4/src/valar/urls.py +0 -7
  50. valar-1.1.4/src/valar.egg-info/SOURCES.txt +0 -31
  51. {valar-1.1.4 → valar-1.2.1}/LICENSE +0 -0
  52. {valar-1.1.4 → valar-1.2.1}/setup.cfg +0 -0
  53. {valar-1.1.4 → valar-1.2.1}/src/valar/__init__.py +0 -0
  54. {valar-1.1.4 → valar-1.2.1}/src/valar/channels/__init__.py +0 -0
  55. {valar-1.1.4/src/valar/classes → valar-1.2.1/src/valar/channels}/counter.py +0 -0
  56. {valar-1.1.4 → valar-1.2.1}/src/valar/channels/mapping.py +0 -0
  57. {valar-1.1.4 → valar-1.2.1}/src/valar/classes/__init__.py +0 -0
  58. {valar-1.1.4/src/valar/frame → valar-1.2.1/src/valar/classes/app_mixins}/__init__.py +0 -0
  59. {valar-1.1.4 → valar-1.2.1}/src/valar/classes/singleton_meta.py +0 -0
  60. {valar-1.1.4/src/valar/migrations → valar-1.2.1/src/valar/dao/defaults}/__init__.py +0 -0
  61. {valar-1.1.4/src/valar/views → valar-1.2.1/src/valar/migrations}/__init__.py +0 -0
  62. {valar-1.1.4 → valar-1.2.1}/src/valar/models/__init__.py +0 -0
  63. {valar-1.1.4 → valar-1.2.1}/src/valar.egg-info/dependency_links.txt +0 -0
  64. {valar-1.1.4 → valar-1.2.1}/src/valar.egg-info/requires.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: valar
3
- Version: 1.1.4
3
+ Version: 1.2.1
4
4
  Summary: valar for morghulis
5
5
  Home-page: https://gitee.com/GRIFFIN120/valar_dev
6
6
  Author: LYP
@@ -27,12 +27,13 @@ Dynamic: requires-python
27
27
  Dynamic: summary
28
28
 
29
29
  valar for morghulis
30
+
30
31
  # 1. install
32
+
31
33
  ```shell
32
34
  pip install valar
33
35
  ```
34
36
 
35
-
36
37
  # 1. settings
37
38
 
38
39
  ```python
@@ -47,16 +48,12 @@ BASE_APP = str(BASE_DIR.name)
47
48
  DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
48
49
  SECRET_KEY = get_random_secret_key()
49
50
 
50
-
51
-
52
51
  """ Valar Options """
53
52
 
54
53
  HANDLER_MAPPING = "%s.urls.channel_mapping" % BASE_APP
55
54
  MONGO_URI = 'mongodb://root:19870120@121.41.111.175:27017/'
56
55
  MINIO_URL = "s3://admin:password@120.27.8.186:9000"
57
56
 
58
-
59
-
60
57
  """ Minimized compulsory settings """
61
58
 
62
59
  DATABASES = {
@@ -69,7 +66,7 @@ INSTALLED_APPS = [
69
66
  'django.contrib.sessions',
70
67
  "corsheaders",
71
68
  'channels',
72
- 'valar',
69
+ 'valar.apps.ValarConfig',
73
70
  ]
74
71
  MIDDLEWARE = [
75
72
  'django.contrib.sessions.middleware.SessionMiddleware',
@@ -99,6 +96,7 @@ FILE_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 100
99
96
  DATA_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 100
100
97
 
101
98
  ```
99
+
102
100
  # 2. asgi
103
101
 
104
102
  ```python
@@ -117,8 +115,8 @@ application = ProtocolTypeRouter({
117
115
  ```
118
116
 
119
117
  # 3. migrate
120
- no need, valar will auto migration
121
118
 
119
+ no need, valar will auto migration
122
120
 
123
121
  # 4. root urls
124
122
 
@@ -126,7 +124,6 @@ no need, valar will auto set urlpatterns
126
124
 
127
125
  # 5. how to use valar_channel
128
126
 
129
-
130
127
  5.1 set HANDLER_MAPPING in settings
131
128
 
132
129
  ```python
@@ -137,13 +134,11 @@ HANDLER_MAPPING = "%s.urls.channel_mapping" % BASE_APP
137
134
 
138
135
  ```python
139
136
  from valar.channels.sender import ValarSocketSender
137
+
138
+
140
139
  def test_handler(sender: ValarSocketSender):
141
140
  data = sender.data
142
- length = data.get('length',30)
143
- counter = sender.create_counter(length)
144
- for i in range(length):
145
- # sync method
146
- sender.to_clients(counter.tick() ,sender.client, wait=True)
141
+ sender.load(data)
147
142
  ```
148
143
 
149
144
  5.3 register handler in channel_mapping
@@ -1,10 +1,11 @@
1
1
  valar for morghulis
2
+
2
3
  # 1. install
4
+
3
5
  ```shell
4
6
  pip install valar
5
7
  ```
6
8
 
7
-
8
9
  # 1. settings
9
10
 
10
11
  ```python
@@ -19,16 +20,12 @@ BASE_APP = str(BASE_DIR.name)
19
20
  DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
20
21
  SECRET_KEY = get_random_secret_key()
21
22
 
22
-
23
-
24
23
  """ Valar Options """
25
24
 
26
25
  HANDLER_MAPPING = "%s.urls.channel_mapping" % BASE_APP
27
26
  MONGO_URI = 'mongodb://root:19870120@121.41.111.175:27017/'
28
27
  MINIO_URL = "s3://admin:password@120.27.8.186:9000"
29
28
 
30
-
31
-
32
29
  """ Minimized compulsory settings """
33
30
 
34
31
  DATABASES = {
@@ -41,7 +38,7 @@ INSTALLED_APPS = [
41
38
  'django.contrib.sessions',
42
39
  "corsheaders",
43
40
  'channels',
44
- 'valar',
41
+ 'valar.apps.ValarConfig',
45
42
  ]
46
43
  MIDDLEWARE = [
47
44
  'django.contrib.sessions.middleware.SessionMiddleware',
@@ -71,6 +68,7 @@ FILE_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 100
71
68
  DATA_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 100
72
69
 
73
70
  ```
71
+
74
72
  # 2. asgi
75
73
 
76
74
  ```python
@@ -89,8 +87,8 @@ application = ProtocolTypeRouter({
89
87
  ```
90
88
 
91
89
  # 3. migrate
92
- no need, valar will auto migration
93
90
 
91
+ no need, valar will auto migration
94
92
 
95
93
  # 4. root urls
96
94
 
@@ -98,7 +96,6 @@ no need, valar will auto set urlpatterns
98
96
 
99
97
  # 5. how to use valar_channel
100
98
 
101
-
102
99
  5.1 set HANDLER_MAPPING in settings
103
100
 
104
101
  ```python
@@ -109,13 +106,11 @@ HANDLER_MAPPING = "%s.urls.channel_mapping" % BASE_APP
109
106
 
110
107
  ```python
111
108
  from valar.channels.sender import ValarSocketSender
109
+
110
+
112
111
  def test_handler(sender: ValarSocketSender):
113
112
  data = sender.data
114
- length = data.get('length',30)
115
- counter = sender.create_counter(length)
116
- for i in range(length):
117
- # sync method
118
- sender.to_clients(counter.tick() ,sender.client, wait=True)
113
+ sender.load(data)
119
114
  ```
120
115
 
121
116
  5.3 register handler in channel_mapping
@@ -16,16 +16,16 @@ requires = [
16
16
 
17
17
  setup(
18
18
  name="valar", # 包名
19
- version="1.1.4", # 版本号
19
+ version="1.2.1", # 版本号
20
20
  author="LYP", # 作者
21
21
  author_email="liuyinpeng@buaa.edu.cn", # 邮箱
22
22
  description="valar for morghulis", # 简短描述
23
23
  long_description=long_description, # 详细说明
24
24
  long_description_content_type="text/markdown", # 详细说明使用标记类型
25
- url="https://gitee.com/GRIFFIN120/valar_dev", # 项目主页
25
+ url="https://gitee.com/GRIFFIN120/valar_dev", # 项目主页
26
26
  packages=find_packages(where="src"), # 需要打包的部分
27
27
  package_dir={"": "src"}, # 设置src目录为根目录
28
28
  python_requires=">=3.9", # 项目支持的Python版本
29
- install_requires=requires, # 项目必须的依赖
29
+ install_requires=requires, # 项目必须的依赖
30
30
  include_package_data=False # 是否包含非Python文件(如资源文件)
31
- )
31
+ )
@@ -0,0 +1,18 @@
1
+ import os
2
+ from django.apps import AppConfig
3
+ from .classes.app_mixins.auto_migration_mixin import AutoMigrationMixin
4
+ from .classes.app_mixins.auto_urlpatterns_mixin import AutoUrlPatternsMixin
5
+
6
+ valar_app = __package__.replace('src.', '')
7
+
8
+
9
+ class ValarConfig(AutoMigrationMixin, AutoUrlPatternsMixin, AppConfig):
10
+ default_auto_field = 'django.db.models.BigAutoField'
11
+ name = __package__
12
+
13
+ def ready(self):
14
+ if os.environ.get('RUN_MAIN') == 'true':
15
+ from .dao.frame import MetaFrame
16
+ getattr(super(), 'set_url', None)()
17
+ getattr(super(), 'auto_migrate', None)()
18
+ MetaFrame()
@@ -1,8 +1,8 @@
1
-
2
1
  from channels.generic.websocket import AsyncJsonWebsocketConsumer
3
2
 
4
3
  VALAR_CHANNEL_GROUP = 'VALAR'
5
4
 
5
+
6
6
  class ValarConsumer(AsyncJsonWebsocketConsumer):
7
7
 
8
8
  def __init__(self):
@@ -24,25 +24,23 @@ class ValarConsumer(AsyncJsonWebsocketConsumer):
24
24
  pass
25
25
 
26
26
  async def user_emit(self, event):
27
- users: list = event.get('users',[])
28
- data = event.get('data',{})
27
+ users: list = event.get('users', [])
28
+ data = event.get('data', {})
29
29
  if self.uid in users:
30
30
  await self.send_json(data)
31
31
 
32
32
  async def client_emit(self, event):
33
- clients: list = event.get('clients',[])
34
- data = event.get('data',{})
33
+ clients: list = event.get('clients', [])
34
+ data = event.get('data', {})
35
35
  if self.client in clients:
36
36
  await self.send_json(data)
37
37
 
38
38
  async def broadcast_emit(self, event):
39
- data = event.get('data',{})
39
+ data = event.get('data', {})
40
40
  await self.send_json(data)
41
41
 
42
42
  async def register_emit(self, event):
43
- users: list = event.get('users', [])
44
- clients: list = event.get('clients',[])
45
- if self.client in clients:
46
- self.uid = users[0]
47
-
48
-
43
+ uid = event.get('uid', )
44
+ client = event.get('client')
45
+ if self.client == client:
46
+ self.uid = uid
@@ -0,0 +1,14 @@
1
+ import asyncio
2
+
3
+ from ..channels.sender import ValarChannelSender
4
+
5
+
6
+ async def execute_channel(method, sender: ValarChannelSender):
7
+ thread = asyncio.to_thread(__execute__, method, sender)
8
+ asyncio.create_task(thread)
9
+
10
+
11
+ def __execute__(method, sender: ValarChannelSender):
12
+ sender.start()
13
+ method(sender)
14
+ sender.stop()
@@ -0,0 +1,116 @@
1
+ import json
2
+ import time
3
+ from datetime import datetime
4
+
5
+ from asgiref.sync import async_to_sync
6
+ from channels.layers import get_channel_layer
7
+ from django.http import HttpRequest
8
+ import threading
9
+ from .consumer import VALAR_CHANNEL_GROUP
10
+
11
+
12
+ class Channel:
13
+
14
+ def __init__(self, request: HttpRequest):
15
+ body = json.loads(request.body)
16
+ self.handler = body.get('handler')
17
+ self.url = body.get('url')
18
+ self.auth = body.get('auth')
19
+ self.broadcast = body.get('broadcast')
20
+ self.data = body.get('data')
21
+
22
+ def to_dict(self, status, payload):
23
+ data = {
24
+ 'handler': self.handler,
25
+ 'url': self.url,
26
+ 'auth': self.auth,
27
+ 'broadcast': self.broadcast,
28
+ 'timestamp': datetime.now().timestamp()
29
+ }
30
+ if status:
31
+ data.update({'status': status})
32
+ if payload:
33
+ data.update({'payload': payload})
34
+ return data
35
+
36
+
37
+ class Sender:
38
+
39
+ def __init__(self, request: HttpRequest):
40
+ self.client = request.headers.get('CLIENT')
41
+ self.uid = request.session.get('UID')
42
+ self.group_send = async_to_sync(get_channel_layer().group_send)
43
+
44
+
45
+ class ValarChannelSender(Sender):
46
+
47
+ def __init__(self, request: HttpRequest, interval=1):
48
+ super().__init__(request)
49
+ self.__channel__ = Channel(request)
50
+ self.data = self.__channel__.data
51
+ self.__payload__ = None
52
+ self.__loading__ = False
53
+ self.__thread__ = None
54
+ self.__lock__ = threading.Lock()
55
+ self.__interval__ = interval
56
+ if self.__channel__.auth and not self.uid:
57
+ raise Exception('Unauthorized!')
58
+
59
+ def _run(self):
60
+ while self.__loading__:
61
+ self.__emit__()
62
+ time.sleep(self.__interval__)
63
+
64
+ def start(self):
65
+ if self.__loading__:
66
+ return # 避免重复启动
67
+ self.__payload__ = None
68
+ self.__loading__ = True
69
+ self.__emit__('start')
70
+ self.__thread__ = threading.Thread(target=self._run, daemon=True)
71
+ self.__thread__.start()
72
+
73
+ def stop(self):
74
+ self.__payload__ = None
75
+ self.__loading__ = False
76
+ self.__emit__('stop')
77
+ if self.__thread__:
78
+ self.__thread__.join()
79
+ self.__thread__ = None
80
+
81
+ def load(self, payload):
82
+ with self.__lock__:
83
+ self.__payload__ = payload
84
+
85
+ def done(self, payload):
86
+ self.__emit__('done', payload)
87
+
88
+ def __emit__(self, status='proceed', data=None):
89
+ scope = 'broadcast' if self.__channel__.broadcast else 'client'
90
+ body = {
91
+ 'type': f'{scope}.emit',
92
+ 'data': self.__channel__.to_dict(status, data or self.__payload__),
93
+ 'clients': [self.client],
94
+ 'users': []
95
+ }
96
+ self.group_send(VALAR_CHANNEL_GROUP, body)
97
+
98
+
99
+ class ValarSocketSender(Sender):
100
+ def __init__(self, request: HttpRequest):
101
+ super().__init__(request)
102
+ if self.uid:
103
+ body = {'type': 'broadcast.emit', 'uid': self.uid, 'client': self.client}
104
+ self.group_send(VALAR_CHANNEL_GROUP, body)
105
+
106
+ def to_users(self, payload, users: list):
107
+ body = {'type': 'user.emit', 'data': payload, 'users': users}
108
+ self.group_send(VALAR_CHANNEL_GROUP, body)
109
+
110
+ def to_clients(self, payload, clients: list):
111
+ body = {'type': 'client.emit', 'data': payload, 'clients': clients}
112
+ self.group_send(VALAR_CHANNEL_GROUP, body)
113
+
114
+ def broadcast(self, payload):
115
+ body = {'type': 'broadcast.emit', 'data': payload}
116
+ self.group_send(VALAR_CHANNEL_GROUP, body)
@@ -1,12 +1,11 @@
1
-
2
1
  from .executer import execute_channel
3
2
  from .mapping import ChannelMapping
4
- from .sender import ValarSocketSender
3
+ from .sender import ValarChannelSender
5
4
  from ..classes.valar_response import ValarResponse
6
5
 
7
6
 
8
7
  async def handel_channel(request, handler):
9
- sender = ValarSocketSender(request)
8
+ sender = ValarChannelSender(request)
10
9
  method = ChannelMapping().get_handler(handler)
11
10
  await execute_channel(method, sender)
12
11
  return ValarResponse(True)
@@ -1,8 +1,8 @@
1
1
  class AutoMigrationMixin:
2
2
  name = None # 子类必须提供
3
+
3
4
  def auto_migrate(self):
4
5
  from django.core.management import call_command
5
- app = self.name.replace('src.','')
6
+ app = self.name.replace('src.', '')
6
7
  call_command('makemigrations', app, interactive=False, verbosity=0)
7
8
  call_command('migrate', app, interactive=False, verbosity=0)
8
-
@@ -3,13 +3,13 @@ import importlib
3
3
  from django.conf import settings
4
4
  from django.urls import path, include
5
5
 
6
+
6
7
  class AutoUrlPatternsMixin:
7
8
  name = None # 子类必须提供
9
+
8
10
  def set_url(self):
9
11
  root = settings.ROOT_URLCONF
10
12
  module = importlib.import_module(root)
11
13
  urlpatterns: list = getattr(module, 'urlpatterns')
12
14
  url = f'{self.name}.urls'
13
- urlpatterns.append(path('data/', include(url)))
14
-
15
-
15
+ urlpatterns.append(path('valar/', include(url)))
@@ -0,0 +1,80 @@
1
+ import json
2
+ from io import BytesIO
3
+ from django.conf import settings
4
+ from urllib3 import BaseHTTPResponse
5
+
6
+ from ..classes.singleton_meta import SingletonMeta
7
+
8
+
9
+ class ValarMinio(metaclass=SingletonMeta):
10
+
11
+ def __init__(self, client, entity):
12
+ self.client = client
13
+ self.bucket_name = f'{settings.BASE_DIR.name}.{entity}'.replace('_', '-').lower()
14
+ if client and not self.client.bucket_exists(self.bucket_name):
15
+ self.client.make_bucket(self.bucket_name)
16
+ self.client.set_bucket_policy(self.bucket_name, self.__generate_policy__())
17
+
18
+ @staticmethod
19
+ def get_object_name(_id, prop, file_name):
20
+ return f"{_id}-{prop}-{file_name}"
21
+
22
+ def upload(self, object_name, _bytes):
23
+ file_data = BytesIO(_bytes)
24
+ file_size = len(_bytes) # file.siz
25
+ self.client.put_object(
26
+ bucket_name=self.bucket_name,
27
+ object_name=object_name,
28
+ data=file_data,
29
+ length=file_size
30
+ )
31
+ return f'{self.bucket_name}/{object_name}'
32
+
33
+ def remove(self, path):
34
+ if path:
35
+ bucket_name, object_name = path.split('/')
36
+ self.client.remove_object(
37
+ bucket_name=bucket_name,
38
+ object_name=object_name
39
+ )
40
+
41
+ def read(self, object_name) -> BytesIO:
42
+ ret: BaseHTTPResponse = self.client.get_object(
43
+ bucket_name=self.bucket_name,
44
+ object_name=object_name
45
+ )
46
+ return BytesIO(ret.read())
47
+
48
+ def __generate_policy__(self):
49
+ return json.dumps({
50
+ "Version": "2012-10-17",
51
+ "Statement": [
52
+ {
53
+ "Sid": "",
54
+ "Effect": "Allow",
55
+ "Principal": {"AWS": "*"},
56
+ "Action": "s3:GetBucketLocation",
57
+ "Resource": f"arn:aws:s3:::{self.bucket_name}"
58
+ },
59
+ {
60
+ "Sid": "",
61
+ "Effect": "Allow",
62
+ "Principal": {"AWS": "*"},
63
+ "Action": "s3:ListBucket",
64
+ "Resource": f"arn:aws:s3:::{self.bucket_name}"
65
+ },
66
+ {
67
+ "Sid": "",
68
+ "Effect": "Allow",
69
+ "Principal": {"AWS": "*"},
70
+ "Action": "s3:GetObject",
71
+ "Resource": f"arn:aws:s3:::{self.bucket_name}/*"
72
+ },
73
+ {
74
+ "Sid": "",
75
+ "Effect": "Allow",
76
+ "Principal": {"AWS": "*"},
77
+ "Action": "s3:PutObject",
78
+ "Resource": f"arn:aws:s3:::{self.bucket_name}/*"
79
+ }
80
+ ]})
@@ -1,7 +1,8 @@
1
1
  from django.http import JsonResponse
2
2
 
3
+
3
4
  class ValarResponse(JsonResponse):
4
- def __init__(self, data, message='', code='info'):
5
+ def __init__(self, data=True, message='', code='info'):
5
6
  self.message = message
6
7
  self.code = code
7
8
  super(ValarResponse, self).__init__(data, safe=False)
@@ -0,0 +1,45 @@
1
+ from ..dao.abstract import AbstractDao
2
+ from ..dao.mon_dao import MonDao
3
+ from ..dao.orm_dao import OrmDao
4
+
5
+
6
+ class Dao(AbstractDao):
7
+
8
+ def __init__(self, entity, db='orm'):
9
+ self.dao = OrmDao(entity) if db == 'orm' else MonDao(entity)
10
+ self.db = db
11
+ self.entity = entity
12
+ self.name = self.dao.name
13
+ self.is_tree = self.dao.is_tree
14
+ self.fields = self.dao.fields
15
+ self.manager = self.dao.manager
16
+
17
+ def save_many(self, array: list):
18
+ self.dao.save_many(array)
19
+
20
+ def save_one(self, item, with_id=False):
21
+ return self.dao.save_one(item, with_id)
22
+
23
+ def delete_one(self, _id):
24
+ return self.dao.delete_one(_id)
25
+
26
+ def find_one(self, _id):
27
+ return self.dao.find_one(_id)
28
+
29
+ def find(self, conditions=None, orders=None, size=0, page=1):
30
+ return self.dao.find(conditions, orders, size, page)
31
+
32
+ def values(self, conditions, props):
33
+ return self.dao.values(conditions, props)
34
+
35
+ def update(self, template, conditions):
36
+ return self.dao.update(template, conditions)
37
+
38
+ def delete(self, conditions=None) -> list:
39
+ return self.dao.delete(conditions)
40
+
41
+ def serialize(self, o, code=None):
42
+ return self.dao.serialize(o, code)
43
+
44
+ def tree(self, root, conditions=None):
45
+ return self.dao.tree(root, conditions)
@@ -0,0 +1,106 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ from bson import ObjectId
4
+
5
+ from ..dao.engine import ValarEngine
6
+
7
+
8
+ class AbstractField(ABC):
9
+ db = None
10
+ entity = None
11
+ prop = None
12
+ label = None
13
+ domain = None
14
+ refer = None
15
+
16
+ @abstractmethod
17
+ def to_dict(self):
18
+ pass
19
+
20
+
21
+ class AbstractDao(ABC):
22
+ engine = ValarEngine()
23
+ db = None
24
+ entity = None
25
+ name = None
26
+ is_tree = False
27
+ fields = {}
28
+
29
+ def props(self, domain=None):
30
+ return [prop for prop, field in self.fields.items() if field.domain == domain or domain is None]
31
+
32
+ def full_props(self):
33
+ return {
34
+ prop: {
35
+ "prop": prop,
36
+ "domain": field.domain,
37
+ "label": field.label,
38
+ }
39
+ for prop, field in self.fields.items()
40
+ }
41
+
42
+ def get_meta_field(self, prop) -> AbstractField:
43
+ return self.fields[prop]
44
+
45
+ @abstractmethod
46
+ def save_one(self, item, with_id=False):
47
+ pass
48
+
49
+ @abstractmethod
50
+ def save_many(self, array: list):
51
+ pass
52
+
53
+ @abstractmethod
54
+ def values(self, conditions, props):
55
+ pass
56
+
57
+ @abstractmethod
58
+ def delete_one(self, _id):
59
+ pass
60
+
61
+ @abstractmethod
62
+ def find_one(self, _id):
63
+ pass
64
+
65
+ @abstractmethod
66
+ def find(self, conditions=None, orders=None, size=0, page=1):
67
+ pass
68
+
69
+ @abstractmethod
70
+ def update(self, template, conditions):
71
+ pass
72
+
73
+ @abstractmethod
74
+ def delete(self, conditions=None) -> list:
75
+ pass
76
+
77
+ @abstractmethod
78
+ def serialize(self, o, code=None):
79
+ pass
80
+
81
+ @abstractmethod
82
+ def tree(self, root, conditions=None):
83
+ pass
84
+
85
+ def search(self, includes=None, excludes=None, orders=None):
86
+ conditions = [{"includes": includes or {}, "excludes": excludes or {}}]
87
+ results, _ = self.find(conditions, orders)
88
+ return results
89
+
90
+ def object_id(self, _id):
91
+ try:
92
+ return int(_id) if self.db == 'orm' else ObjectId(_id)
93
+ except Exception:
94
+ return None
95
+
96
+ # @abstractmethod
97
+ # def values(self, props, conditions, orders=None):
98
+ # pass
99
+ #
100
+ # @abstractmethod
101
+ # def group(self, props, conditions, orders=None):
102
+ # pass
103
+ #
104
+ # @abstractmethod
105
+ # def count(self, props, conditions):
106
+ # pass