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.
- {valar-1.1.3/src/valar.egg-info → valar-1.2.0}/PKG-INFO +50 -57
- {valar-1.1.3 → valar-1.2.0}/README.md +49 -56
- {valar-1.1.3 → valar-1.2.0}/setup.py +4 -4
- valar-1.2.0/src/valar/apps.py +18 -0
- {valar-1.1.3 → valar-1.2.0}/src/valar/channels/consumer.py +10 -12
- valar-1.2.0/src/valar/channels/executer.py +14 -0
- valar-1.2.0/src/valar/channels/sender.py +116 -0
- {valar-1.1.3 → valar-1.2.0}/src/valar/channels/views.py +2 -3
- valar-1.2.0/src/valar/classes/app_mixins/auto_migration_mixin.py +8 -0
- {valar-1.1.3/src/valar/classes → valar-1.2.0/src/valar/classes/app_mixins}/auto_urlpatterns_mixin.py +3 -3
- valar-1.2.0/src/valar/classes/valar_minio.py +80 -0
- {valar-1.1.3 → valar-1.2.0}/src/valar/classes/valar_response.py +2 -1
- valar-1.2.0/src/valar/dao/__init__.py +45 -0
- valar-1.2.0/src/valar/dao/abstract.py +106 -0
- valar-1.2.0/src/valar/dao/defaults/field_keys_default.py +48 -0
- valar-1.2.0/src/valar/dao/defaults/field_values_default.py +135 -0
- valar-1.2.0/src/valar/dao/defaults/view_defaults.py +26 -0
- valar-1.2.0/src/valar/dao/engine.py +80 -0
- valar-1.2.0/src/valar/dao/frame.py +189 -0
- valar-1.2.0/src/valar/dao/meta.py +128 -0
- valar-1.2.0/src/valar/dao/mon_dao.py +113 -0
- valar-1.2.0/src/valar/dao/mon_field.py +23 -0
- valar-1.2.0/src/valar/dao/orm_dao.py +304 -0
- valar-1.2.0/src/valar/dao/orm_field.py +142 -0
- valar-1.2.0/src/valar/dao/query.py +36 -0
- valar-1.2.0/src/valar/migrations/0001_initial.py +149 -0
- {valar-1.1.3 → valar-1.2.0}/src/valar/models/core.py +16 -10
- {valar-1.1.3 → valar-1.2.0}/src/valar/models/frame.py +4 -7
- {valar-1.1.3 → valar-1.2.0}/src/valar/models/meta.py +19 -16
- valar-1.2.0/src/valar/urls.py +29 -0
- valar-1.2.0/src/valar/views/__init__.py +0 -0
- valar-1.2.0/src/valar/views/file.py +49 -0
- valar-1.2.0/src/valar/views/handler.py +33 -0
- valar-1.2.0/src/valar/views/meta.py +150 -0
- valar-1.2.0/src/valar/views/rest.py +90 -0
- {valar-1.1.3 → valar-1.2.0/src/valar.egg-info}/PKG-INFO +50 -57
- valar-1.2.0/src/valar.egg-info/SOURCES.txt +50 -0
- valar-1.1.3/src/valar/apps.py +0 -20
- valar-1.1.3/src/valar/channels/executer.py +0 -13
- valar-1.1.3/src/valar/channels/sender.py +0 -64
- valar-1.1.3/src/valar/classes/auto_migration_mixin.py +0 -7
- valar-1.1.3/src/valar/urls.py +0 -7
- valar-1.1.3/src/valar.egg-info/SOURCES.txt +0 -30
- {valar-1.1.3 → valar-1.2.0}/LICENSE +0 -0
- {valar-1.1.3 → valar-1.2.0}/setup.cfg +0 -0
- {valar-1.1.3 → valar-1.2.0}/src/valar/__init__.py +0 -0
- {valar-1.1.3 → valar-1.2.0}/src/valar/channels/__init__.py +0 -0
- {valar-1.1.3/src/valar/classes → valar-1.2.0/src/valar/channels}/counter.py +0 -0
- {valar-1.1.3 → valar-1.2.0}/src/valar/channels/mapping.py +0 -0
- {valar-1.1.3 → valar-1.2.0}/src/valar/classes/__init__.py +0 -0
- {valar-1.1.3/src/valar/frame → valar-1.2.0/src/valar/classes/app_mixins}/__init__.py +0 -0
- {valar-1.1.3 → valar-1.2.0}/src/valar/classes/singleton_meta.py +0 -0
- {valar-1.1.3/src/valar/migrations → valar-1.2.0/src/valar/dao/defaults}/__init__.py +0 -0
- {valar-1.1.3/src/valar/views → valar-1.2.0/src/valar/migrations}/__init__.py +0 -0
- {valar-1.1.3 → valar-1.2.0}/src/valar/models/__init__.py +0 -0
- {valar-1.1.3 → valar-1.2.0}/src/valar.egg-info/dependency_links.txt +0 -0
- {valar-1.1.3 → valar-1.2.0}/src/valar.egg-info/requires.txt +0 -0
- {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.
|
|
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
|
-
"""
|
|
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 =
|
|
48
|
-
|
|
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
|
-
'
|
|
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
|
-
|
|
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
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
134
|
-
from django.urls import path, include
|
|
125
|
+
no need, valar will auto set urlpatterns
|
|
135
126
|
|
|
136
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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',
|
|
158
|
-
counter =
|
|
142
|
+
length = data.get('length',30)
|
|
143
|
+
counter = sender.create_counter(length)
|
|
159
144
|
for i in range(length):
|
|
160
|
-
|
|
161
|
-
sender.to_clients(counter.tick(),
|
|
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
|
-
"""
|
|
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 =
|
|
20
|
-
|
|
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
|
-
'
|
|
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
|
-
|
|
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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
106
|
-
from django.urls import path, include
|
|
97
|
+
no need, valar will auto set urlpatterns
|
|
107
98
|
|
|
108
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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',
|
|
130
|
-
counter =
|
|
114
|
+
length = data.get('length',30)
|
|
115
|
+
counter = sender.create_counter(length)
|
|
131
116
|
for i in range(length):
|
|
132
|
-
|
|
133
|
-
sender.to_clients(counter.tick(),
|
|
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.
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
if self.client
|
|
46
|
-
self.uid =
|
|
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
|
|
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 =
|
|
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
|
+
|
{valar-1.1.3/src/valar/classes → valar-1.2.0/src/valar/classes/app_mixins}/auto_urlpatterns_mixin.py
RENAMED
|
@@ -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('
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
urlpatterns.append(path('valar/', include(url)))
|