valar 1.1.3__tar.gz → 1.2.0__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 (58) hide show
  1. {valar-1.1.3/src/valar.egg-info → valar-1.2.0}/PKG-INFO +50 -57
  2. {valar-1.1.3 → valar-1.2.0}/README.md +49 -56
  3. {valar-1.1.3 → valar-1.2.0}/setup.py +4 -4
  4. valar-1.2.0/src/valar/apps.py +18 -0
  5. {valar-1.1.3 → valar-1.2.0}/src/valar/channels/consumer.py +10 -12
  6. valar-1.2.0/src/valar/channels/executer.py +14 -0
  7. valar-1.2.0/src/valar/channels/sender.py +116 -0
  8. {valar-1.1.3 → valar-1.2.0}/src/valar/channels/views.py +2 -3
  9. valar-1.2.0/src/valar/classes/app_mixins/auto_migration_mixin.py +8 -0
  10. {valar-1.1.3/src/valar/classes → valar-1.2.0/src/valar/classes/app_mixins}/auto_urlpatterns_mixin.py +3 -3
  11. valar-1.2.0/src/valar/classes/valar_minio.py +80 -0
  12. {valar-1.1.3 → valar-1.2.0}/src/valar/classes/valar_response.py +2 -1
  13. valar-1.2.0/src/valar/dao/__init__.py +45 -0
  14. valar-1.2.0/src/valar/dao/abstract.py +106 -0
  15. valar-1.2.0/src/valar/dao/defaults/field_keys_default.py +48 -0
  16. valar-1.2.0/src/valar/dao/defaults/field_values_default.py +135 -0
  17. valar-1.2.0/src/valar/dao/defaults/view_defaults.py +26 -0
  18. valar-1.2.0/src/valar/dao/engine.py +80 -0
  19. valar-1.2.0/src/valar/dao/frame.py +189 -0
  20. valar-1.2.0/src/valar/dao/meta.py +128 -0
  21. valar-1.2.0/src/valar/dao/mon_dao.py +113 -0
  22. valar-1.2.0/src/valar/dao/mon_field.py +23 -0
  23. valar-1.2.0/src/valar/dao/orm_dao.py +304 -0
  24. valar-1.2.0/src/valar/dao/orm_field.py +142 -0
  25. valar-1.2.0/src/valar/dao/query.py +36 -0
  26. valar-1.2.0/src/valar/migrations/0001_initial.py +149 -0
  27. {valar-1.1.3 → valar-1.2.0}/src/valar/models/core.py +16 -10
  28. {valar-1.1.3 → valar-1.2.0}/src/valar/models/frame.py +4 -7
  29. {valar-1.1.3 → valar-1.2.0}/src/valar/models/meta.py +19 -16
  30. valar-1.2.0/src/valar/urls.py +29 -0
  31. valar-1.2.0/src/valar/views/__init__.py +0 -0
  32. valar-1.2.0/src/valar/views/file.py +49 -0
  33. valar-1.2.0/src/valar/views/handler.py +33 -0
  34. valar-1.2.0/src/valar/views/meta.py +150 -0
  35. valar-1.2.0/src/valar/views/rest.py +90 -0
  36. {valar-1.1.3 → valar-1.2.0/src/valar.egg-info}/PKG-INFO +50 -57
  37. valar-1.2.0/src/valar.egg-info/SOURCES.txt +50 -0
  38. valar-1.1.3/src/valar/apps.py +0 -20
  39. valar-1.1.3/src/valar/channels/executer.py +0 -13
  40. valar-1.1.3/src/valar/channels/sender.py +0 -64
  41. valar-1.1.3/src/valar/classes/auto_migration_mixin.py +0 -7
  42. valar-1.1.3/src/valar/urls.py +0 -7
  43. valar-1.1.3/src/valar.egg-info/SOURCES.txt +0 -30
  44. {valar-1.1.3 → valar-1.2.0}/LICENSE +0 -0
  45. {valar-1.1.3 → valar-1.2.0}/setup.cfg +0 -0
  46. {valar-1.1.3 → valar-1.2.0}/src/valar/__init__.py +0 -0
  47. {valar-1.1.3 → valar-1.2.0}/src/valar/channels/__init__.py +0 -0
  48. {valar-1.1.3/src/valar/classes → valar-1.2.0/src/valar/channels}/counter.py +0 -0
  49. {valar-1.1.3 → valar-1.2.0}/src/valar/channels/mapping.py +0 -0
  50. {valar-1.1.3 → valar-1.2.0}/src/valar/classes/__init__.py +0 -0
  51. {valar-1.1.3/src/valar/frame → valar-1.2.0/src/valar/classes/app_mixins}/__init__.py +0 -0
  52. {valar-1.1.3 → valar-1.2.0}/src/valar/classes/singleton_meta.py +0 -0
  53. {valar-1.1.3/src/valar/migrations → valar-1.2.0/src/valar/dao/defaults}/__init__.py +0 -0
  54. {valar-1.1.3/src/valar/views → valar-1.2.0/src/valar/migrations}/__init__.py +0 -0
  55. {valar-1.1.3 → valar-1.2.0}/src/valar/models/__init__.py +0 -0
  56. {valar-1.1.3 → valar-1.2.0}/src/valar.egg-info/dependency_links.txt +0 -0
  57. {valar-1.1.3 → valar-1.2.0}/src/valar.egg-info/requires.txt +0 -0
  58. {valar-1.1.3 → valar-1.2.0}/src/valar.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: valar
3
- Version: 1.1.3
3
+ Version: 1.2.0
4
4
  Summary: valar for morghulis
5
5
  Home-page: https://gitee.com/GRIFFIN120/valar_dev
6
6
  Author: LYP
@@ -36,16 +36,28 @@ pip install valar
36
36
  # 1. settings
37
37
 
38
38
  ```python
39
-
39
+ from django.core.management.utils import get_random_secret_key
40
40
  from pathlib import Path
41
41
 
42
- """ Compulsory settings """
42
+ """ Compulsory settings """
43
+
43
44
  DEBUG = True
44
45
  BASE_DIR = Path(__file__).resolve().parent.parent
45
46
  BASE_APP = str(BASE_DIR.name)
46
47
  DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
47
- SECRET_KEY = 'django-insecure-of@tfouoq^_f$l!yki#m=6j7)@&kjri$1_$!mca-=%7=+@f@5^'
48
- """ Minimized compulsory settings """
48
+ SECRET_KEY = get_random_secret_key()
49
+
50
+
51
+
52
+ """ Valar Options """
53
+
54
+ HANDLER_MAPPING = "%s.urls.channel_mapping" % BASE_APP
55
+ MONGO_URI = 'mongodb://root:19870120@121.41.111.175:27017/'
56
+ MINIO_URL = "s3://admin:password@120.27.8.186:9000"
57
+
58
+
59
+
60
+ """ Minimized compulsory settings """
49
61
 
50
62
  DATABASES = {
51
63
  'default': {
@@ -53,55 +65,38 @@ DATABASES = {
53
65
  'NAME': BASE_DIR / 'db.sqlite3',
54
66
  }
55
67
  }
56
-
57
68
  INSTALLED_APPS = [
58
69
  'django.contrib.sessions',
59
70
  "corsheaders",
60
71
  'channels',
61
- 'src.valar.data',
72
+ 'valar',
62
73
  ]
63
-
64
74
  MIDDLEWARE = [
65
75
  'django.contrib.sessions.middleware.SessionMiddleware',
66
76
  'corsheaders.middleware.CorsMiddleware',
67
77
  'django.middleware.common.CommonMiddleware',
68
78
  ]
69
-
70
79
  CHANNEL_LAYERS = {
71
80
  "default": {
72
81
  "BACKEND": "channels.layers.InMemoryChannelLayer"
73
82
  }
74
83
  }
75
-
76
84
  CORS_ORIGIN_ALLOW_ALL = True
77
85
  CORS_ALLOW_CREDENTIALS = True
78
86
  ROOT_URLCONF = "%s.urls" % BASE_APP
79
87
  ASGI_APPLICATION = "%s.asgi.application" % BASE_APP
80
88
 
81
- MONGO = {
82
- 'host': '<IP>',
83
- 'port': '<PORT>',
84
- "username": "<USERNAME>",
85
- "password": '<PASSWORD>'
86
- }
87
-
88
- MINIO = {
89
- 'endpoint': '<IP>:<PORT>',
90
- 'access_key': '<USERNAME>',
91
- "secret_key": "<PASSWORD>",
92
- 'secure': False
93
- }
89
+ """ Optional settings """
94
90
 
95
- """ Optional settings """
96
- # ALLOWED_HOSTS = ['*']
97
- # LANGUAGE_CODE = 'en-us'
98
- # TIME_ZONE = 'Asia/Shanghai'
99
- # USE_I18N = True
100
- # USE_TZ = False
101
- # SESSION_SAVE_EVERY_REQUEST = True
102
- # SESSION_COOKIE_AGE = 60 * 60
103
- # FILE_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 100
104
- # DATA_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 100
91
+ ALLOWED_HOSTS = ['*']
92
+ LANGUAGE_CODE = 'en-us'
93
+ TIME_ZONE = 'Asia/Shanghai'
94
+ USE_I18N = True
95
+ USE_TZ = False
96
+ SESSION_SAVE_EVERY_REQUEST = True
97
+ SESSION_COOKIE_AGE = 60 * 60
98
+ FILE_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 100
99
+ DATA_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 100
105
100
 
106
101
  ```
107
102
  # 2. asgi
@@ -110,7 +105,7 @@ MINIO = {
110
105
  from django.core.asgi import get_asgi_application
111
106
  from channels.routing import ProtocolTypeRouter, URLRouter
112
107
  from django.urls import re_path
113
- from src.valar.channels import ValarConsumer
108
+ from valar.channels.consumer import ValarConsumer
114
109
 
115
110
  application = ProtocolTypeRouter({
116
111
  'http': get_asgi_application(),
@@ -122,41 +117,39 @@ application = ProtocolTypeRouter({
122
117
  ```
123
118
 
124
119
  # 3. migrate
125
- ```shell
126
- python manage.py makemigrations
127
- python manage.py migrate
128
- ```
120
+ no need, valar will auto migration
129
121
 
130
122
 
131
123
  # 4. root urls
132
124
 
133
- ```python
134
- from django.urls import path, include
125
+ no need, valar will auto set urlpatterns
135
126
 
136
- urlpatterns = [
137
- path('data/', include('src.valar.data.urls')),
138
- ]
127
+ # 5. how to use valar_channel
139
128
 
140
- channel_mapping = {
141
- # 'test': test_handler
142
- }
143
- ```
144
129
 
145
- # 5. channel_handler
130
+ 5.1 set HANDLER_MAPPING in settings
146
131
 
147
132
  ```python
133
+ HANDLER_MAPPING = "%s.urls.channel_mapping" % BASE_APP
134
+ ```
148
135
 
149
- import time
150
-
151
- from src.valar.channels.sender import ValarSocketSender
152
- from src.valar import Counter
153
-
136
+ 5.2 create a handler
154
137
 
138
+ ```python
139
+ from valar.channels.sender import ValarSocketSender
155
140
  def test_handler(sender: ValarSocketSender):
156
141
  data = sender.data
157
- length = data.get('length', 50)
158
- counter = Counter(length)
142
+ length = data.get('length',30)
143
+ counter = sender.create_counter(length)
159
144
  for i in range(length):
160
- time.sleep(0.1)
161
- sender.to_clients(counter.tick(), sender.client, wait=True)
145
+ # sync method
146
+ sender.to_clients(counter.tick() ,sender.client, wait=True)
147
+ ```
148
+
149
+ 5.3 register handler in channel_mapping
150
+
151
+ ```python
152
+ channel_mapping = {
153
+ 'test': test_handler,
154
+ }
162
155
  ```
@@ -8,16 +8,28 @@ pip install valar
8
8
  # 1. settings
9
9
 
10
10
  ```python
11
-
11
+ from django.core.management.utils import get_random_secret_key
12
12
  from pathlib import Path
13
13
 
14
- """ Compulsory settings """
14
+ """ Compulsory settings """
15
+
15
16
  DEBUG = True
16
17
  BASE_DIR = Path(__file__).resolve().parent.parent
17
18
  BASE_APP = str(BASE_DIR.name)
18
19
  DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
19
- SECRET_KEY = 'django-insecure-of@tfouoq^_f$l!yki#m=6j7)@&kjri$1_$!mca-=%7=+@f@5^'
20
- """ Minimized compulsory settings """
20
+ SECRET_KEY = get_random_secret_key()
21
+
22
+
23
+
24
+ """ Valar Options """
25
+
26
+ HANDLER_MAPPING = "%s.urls.channel_mapping" % BASE_APP
27
+ MONGO_URI = 'mongodb://root:19870120@121.41.111.175:27017/'
28
+ MINIO_URL = "s3://admin:password@120.27.8.186:9000"
29
+
30
+
31
+
32
+ """ Minimized compulsory settings """
21
33
 
22
34
  DATABASES = {
23
35
  'default': {
@@ -25,55 +37,38 @@ DATABASES = {
25
37
  'NAME': BASE_DIR / 'db.sqlite3',
26
38
  }
27
39
  }
28
-
29
40
  INSTALLED_APPS = [
30
41
  'django.contrib.sessions',
31
42
  "corsheaders",
32
43
  'channels',
33
- 'src.valar.data',
44
+ 'valar',
34
45
  ]
35
-
36
46
  MIDDLEWARE = [
37
47
  'django.contrib.sessions.middleware.SessionMiddleware',
38
48
  'corsheaders.middleware.CorsMiddleware',
39
49
  'django.middleware.common.CommonMiddleware',
40
50
  ]
41
-
42
51
  CHANNEL_LAYERS = {
43
52
  "default": {
44
53
  "BACKEND": "channels.layers.InMemoryChannelLayer"
45
54
  }
46
55
  }
47
-
48
56
  CORS_ORIGIN_ALLOW_ALL = True
49
57
  CORS_ALLOW_CREDENTIALS = True
50
58
  ROOT_URLCONF = "%s.urls" % BASE_APP
51
59
  ASGI_APPLICATION = "%s.asgi.application" % BASE_APP
52
60
 
53
- MONGO = {
54
- 'host': '<IP>',
55
- 'port': '<PORT>',
56
- "username": "<USERNAME>",
57
- "password": '<PASSWORD>'
58
- }
59
-
60
- MINIO = {
61
- 'endpoint': '<IP>:<PORT>',
62
- 'access_key': '<USERNAME>',
63
- "secret_key": "<PASSWORD>",
64
- 'secure': False
65
- }
61
+ """ Optional settings """
66
62
 
67
- """ Optional settings """
68
- # ALLOWED_HOSTS = ['*']
69
- # LANGUAGE_CODE = 'en-us'
70
- # TIME_ZONE = 'Asia/Shanghai'
71
- # USE_I18N = True
72
- # USE_TZ = False
73
- # SESSION_SAVE_EVERY_REQUEST = True
74
- # SESSION_COOKIE_AGE = 60 * 60
75
- # FILE_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 100
76
- # DATA_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 100
63
+ ALLOWED_HOSTS = ['*']
64
+ LANGUAGE_CODE = 'en-us'
65
+ TIME_ZONE = 'Asia/Shanghai'
66
+ USE_I18N = True
67
+ USE_TZ = False
68
+ SESSION_SAVE_EVERY_REQUEST = True
69
+ SESSION_COOKIE_AGE = 60 * 60
70
+ FILE_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 100
71
+ DATA_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 100
77
72
 
78
73
  ```
79
74
  # 2. asgi
@@ -82,7 +77,7 @@ MINIO = {
82
77
  from django.core.asgi import get_asgi_application
83
78
  from channels.routing import ProtocolTypeRouter, URLRouter
84
79
  from django.urls import re_path
85
- from src.valar.channels import ValarConsumer
80
+ from valar.channels.consumer import ValarConsumer
86
81
 
87
82
  application = ProtocolTypeRouter({
88
83
  'http': get_asgi_application(),
@@ -94,41 +89,39 @@ application = ProtocolTypeRouter({
94
89
  ```
95
90
 
96
91
  # 3. migrate
97
- ```shell
98
- python manage.py makemigrations
99
- python manage.py migrate
100
- ```
92
+ no need, valar will auto migration
101
93
 
102
94
 
103
95
  # 4. root urls
104
96
 
105
- ```python
106
- from django.urls import path, include
97
+ no need, valar will auto set urlpatterns
107
98
 
108
- urlpatterns = [
109
- path('data/', include('src.valar.data.urls')),
110
- ]
99
+ # 5. how to use valar_channel
111
100
 
112
- channel_mapping = {
113
- # 'test': test_handler
114
- }
115
- ```
116
101
 
117
- # 5. channel_handler
102
+ 5.1 set HANDLER_MAPPING in settings
118
103
 
119
104
  ```python
105
+ HANDLER_MAPPING = "%s.urls.channel_mapping" % BASE_APP
106
+ ```
120
107
 
121
- import time
122
-
123
- from src.valar.channels.sender import ValarSocketSender
124
- from src.valar import Counter
125
-
108
+ 5.2 create a handler
126
109
 
110
+ ```python
111
+ from valar.channels.sender import ValarSocketSender
127
112
  def test_handler(sender: ValarSocketSender):
128
113
  data = sender.data
129
- length = data.get('length', 50)
130
- counter = Counter(length)
114
+ length = data.get('length',30)
115
+ counter = sender.create_counter(length)
131
116
  for i in range(length):
132
- time.sleep(0.1)
133
- sender.to_clients(counter.tick(), sender.client, wait=True)
117
+ # sync method
118
+ sender.to_clients(counter.tick() ,sender.client, wait=True)
119
+ ```
120
+
121
+ 5.3 register handler in channel_mapping
122
+
123
+ ```python
124
+ channel_mapping = {
125
+ 'test': test_handler,
126
+ }
134
127
  ```
@@ -16,16 +16,16 @@ requires = [
16
16
 
17
17
  setup(
18
18
  name="valar", # 包名
19
- version="1.1.3", # 版本号
19
+ version="1.2.0", # 版本号
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)
@@ -0,0 +1,8 @@
1
+ class AutoMigrationMixin:
2
+ name = None # 子类必须提供
3
+ def auto_migrate(self):
4
+ from django.core.management import call_command
5
+ app = self.name.replace('src.','')
6
+ call_command('makemigrations', app, interactive=False, verbosity=0)
7
+ 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)))