Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Sign in
Toggle navigation
R
red-ci-cd
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
red-group-test
red-ci-cd
Commits
fe520cc9
Commit
fe520cc9
authored
Sep 03, 2019
by
Gladys Forte
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
notification
parent
bc2be688
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
501 additions
and
1 deletion
+501
-1
app/applicationlayer/management/notification/consumers.py
app/applicationlayer/management/notification/consumers.py
+46
-0
app/applicationlayer/management/notification/routing.py
app/applicationlayer/management/notification/routing.py
+8
-0
app/applicationlayer/management/notification/serializers.py
app/applicationlayer/management/notification/serializers.py
+11
-0
app/applicationlayer/management/notification/utils_notif.py
app/applicationlayer/management/notification/utils_notif.py
+16
-0
app/applicationlayer/management/notification/views.py
app/applicationlayer/management/notification/views.py
+198
-0
app/applicationlayer/urls.py
app/applicationlayer/urls.py
+4
-0
app/entities/enums.py
app/entities/enums.py
+12
-0
app/entities/migrations/0002_notification.py
app/entities/migrations/0002_notification.py
+34
-0
app/entities/migrations/0003_auto_20190903_1725.py
app/entities/migrations/0003_auto_20190903_1725.py
+23
-0
app/entities/models.py
app/entities/models.py
+37
-0
app/entities/templates/chat/index.html
app/entities/templates/chat/index.html
+27
-0
app/entities/templates/chat/room.html
app/entities/templates/chat/room.html
+47
-0
config/routing.py
config/routing.py
+13
-0
config/settings/base.py
config/settings/base.py
+14
-1
config/settings/local.py
config/settings/local.py
+2
-0
config/urls.py
config/urls.py
+6
-0
env.template.ini
env.template.ini
+3
-0
No files found.
app/applicationlayer/management/notification/consumers.py
0 → 100644
View file @
fe520cc9
# chat/consumers.py
from
channels.generic.websocket
import
AsyncWebsocketConsumer
import
json
class
ChatConsumer
(
AsyncWebsocketConsumer
):
async
def
connect
(
self
):
self
.
room_name
=
self
.
scope
[
'url_route'
][
'kwargs'
][
'room_name'
]
self
.
room_group_name
=
'chat_
%
s'
%
self
.
room_name
# Join room group
await
self
.
channel_layer
.
group_add
(
self
.
room_group_name
,
self
.
channel_name
)
await
self
.
accept
()
async
def
disconnect
(
self
,
close_code
):
# Leave room group
await
self
.
channel_layer
.
group_discard
(
self
.
room_group_name
,
self
.
channel_name
)
# Receive message from WebSocket
async
def
receive
(
self
,
text_data
):
text_data_json
=
json
.
loads
(
text_data
)
message
=
text_data_json
[
'message'
]
# Send message to room group
await
self
.
channel_layer
.
group_send
(
self
.
room_group_name
,
{
'type'
:
'chat_message'
,
'message'
:
message
}
)
# Receive message from room group
async
def
chat_message
(
self
,
event
):
message
=
event
[
'message'
]
# Send message to WebSocket
await
self
.
send
(
text_data
=
json
.
dumps
({
'message'
:
message
}))
\ No newline at end of file
app/applicationlayer/management/notification/routing.py
0 → 100644
View file @
fe520cc9
# chat/routing.py
from
django.conf.urls
import
url
from
app.applicationlayer.management.notification
import
consumers
websocket_urlpatterns
=
[
url
(
r'^ws/chat/(?P<room_name>[^/]+)/$'
,
consumers
.
ChatConsumer
),
]
\ No newline at end of file
app/applicationlayer/management/notification/serializers.py
0 → 100644
View file @
fe520cc9
from
rest_framework
import
serializers
from
app.entities
import
models
from
django.conf
import
settings
class
NotificationSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
models
.
Notification
fields
=
'__all__'
read_only_fields
=
[
'code'
]
\ No newline at end of file
app/applicationlayer/management/notification/utils_notif.py
0 → 100644
View file @
fe520cc9
from
django.conf
import
settings
from
websocket
import
create_connection
import
json
REALTIMESERVER_IP
=
settings
.
REALTIMESERVER_IP
def
send_broadcast_message
(
room_name
,
sender
,
message
):
# ws = create_connection(f"ws://{REALTIMESERVER_IP}/ws/realtimeserver/{room_name}/")
ws
=
create_connection
(
f
"ws://{REALTIMESERVER_IP}/ws/chat/{room_name}/"
)
data
=
{
'sender'
:
sender
,
'message'
:
message
}
ws
.
send
(
json
.
dumps
(
data
))
ws
.
close
()
\ No newline at end of file
app/applicationlayer/management/notification/views.py
0 → 100644
View file @
fe520cc9
from
django.shortcuts
import
render
from
django.utils.safestring
import
mark_safe
import
json
from
rest_framework
import
viewsets
as
meviewsets
from
app.applicationlayer.management.notification
import
serializers
from
app.entities
import
models
from
app.applicationlayer
import
paginators
from
datetime
import
datetime
from
rest_framework.response
import
Response
from
rest_framework
import
status
from
django.conf
import
settings
from
app.applicationlayer.management.notification.utils_notif
import
(
send_broadcast_message
)
from
app.applicationlayer.utils
import
(
status_message_response
,
CustomPagination
)
from
rest_framework.exceptions
import
ValidationError
from
django.shortcuts
import
render
,
redirect
,
get_object_or_404
from
rest_framework.decorators
import
action
from
rest_framework.views
import
APIView
class
NotificationsViewset
(
meviewsets
.
ModelViewSet
):
lookup_field
=
'account_no'
queryset
=
models
.
Notification
.
objects
.
all
()
serializer_class
=
serializers
.
NotificationSerializer
pagination_class
=
CustomPagination
def
list
(
self
,
request
,
*
args
,
**
kwargs
):
# try:
req
=
self
.
request
account_no
=
req
.
query_params
.
get
(
'account_no'
)
app
=
req
.
query_params
.
get
(
'app_code'
)
if
account_no
:
queryset
=
models
.
Notification
.
objects
.
filter
(
account_no
=
account_no
)
.
order_by
(
'-created'
)
queryset
=
self
.
filter_queryset
(
queryset
)
unseen
=
models
.
Notification
.
objects
.
filter
(
account_no
=
account_no
,
is_read
=
False
)
.
count
()
if
app
:
queryset
=
models
.
Notification
.
objects
.
filter
(
account_no
=
account_no
,
app
=
app
)
.
order_by
(
'-created'
)
queryset
=
self
.
filter_queryset
(
queryset
)
unseen
=
models
.
Notification
.
objects
.
filter
(
account_no
=
account_no
,
app
=
app
,
is_read
=
False
)
.
count
()
else
:
queryset
=
models
.
Notification
.
objects
.
all
()
.
order_by
(
'-created'
)
queryset
=
self
.
filter_queryset
(
queryset
)
unseen
=
models
.
Notification
.
objects
.
filter
(
is_read
=
False
)
.
count
()
if
not
queryset
:
message
=
status_message_response
(
200
,
'success'
,
'No records found'
,
[]
)
return
Response
(
message
)
serializer
=
self
.
get_serializer
(
queryset
,
many
=
True
)
page
=
self
.
paginate_queryset
(
queryset
)
if
page
is
not
None
:
serializer
=
self
.
get_serializer
(
page
,
many
=
True
)
message
=
{
'unseen'
:
unseen
,
'code'
:
200
,
'status'
:
'success'
,
'message'
:
'List of Notifications found'
,
'results'
:
serializer
.
data
}
return
self
.
get_paginated_response
(
message
)
# return Response(serializer.data)
# except Exception as e:
# message = status_message_response(
# 500, 'failed',
# 'Request was not able to process' + str(e), [])
# return Response(message,
# status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@
action
(
methods
=
[
"PATCH"
],
detail
=
True
)
def
seen
(
self
,
request
,
account_no
=
None
,
**
kwargs
):
try
:
account_no
=
self
.
kwargs
[
'account_no'
]
print
(
account_no
)
models
.
Notification
.
objects
.
filter
(
account_no
=
account_no
,
id__in
=
request
.
data
[
'ids'
])
.
update
(
is_read
=
True
,
modified
=
datetime
.
now
(),
modifiedby
=
account_no
)
message
=
status_message_response
(
200
,
'success'
,
'Status successfully updated'
,
"None"
)
return
Response
(
message
)
except
Exception
as
e
:
message
=
status_message_response
(
500
,
'failed'
,
'Request was not able to process'
+
str
(
e
),
[]
)
return
Response
(
message
,
status
=
status
.
HTTP_500_INTERNAL_SERVER_ERROR
)
@
action
(
methods
=
[
"PATCH"
],
detail
=
True
)
def
seenall
(
self
,
request
,
account_no
=
None
,
**
kwargs
):
try
:
account_no
=
self
.
kwargs
[
'account_no'
]
print
(
account_no
)
models
.
Notification
.
objects
.
filter
(
account_no
=
account_no
)
.
update
(
is_read
=
True
,
modified
=
datetime
.
now
(),
modifiedby
=
account_no
)
message
=
status_message_response
(
200
,
'success'
,
'Status successfully updated'
,
"None"
)
return
Response
(
message
)
except
Exception
as
e
:
message
=
status_message_response
(
500
,
'failed'
,
'Request was not able to process'
+
str
(
e
),
[]
)
return
Response
(
message
,
status
=
status
.
HTTP_500_INTERNAL_SERVER_ERROR
)
def
create
(
self
,
request
,
*
args
,
**
kwargs
):
serializer
=
serializers
.
NotificationSerializer
(
data
=
request
.
data
)
try
:
if
serializer
.
is_valid
():
x
=
serializer
.
save
()
x
.
created
=
datetime
.
now
()
x
.
save
()
message
=
{
'code'
:
201
,
'status'
:
'success'
,
'message'
:
'Notification created.'
,
'results'
:
serializer
.
data
}
ROOM
=
serializer
.
data
[
'account_no'
]
SENDER
=
serializer
.
data
[
'sender_account_no'
]
send_broadcast_message
(
ROOM
,
SENDER
,
'NEW NOTIFICATIONS'
)
return
Response
(
message
,
status
=
status
.
HTTP_201_CREATED
)
except
ValidationError
as
e
:
message
=
{
'code'
:
400
,
'status'
:
'failed'
,
'message'
:
str
(
e
),
}
return
Response
(
message
,
status
=
status
.
HTTP_400_BAD_REQUEST
)
except
Exception
as
e
:
message
=
{
'code'
:
500
,
'status'
:
'failed'
,
'message'
:
'Request was not able to process'
+
str
(
e
.
__class__
)
}
return
Response
(
message
,
status
=
status
.
HTTP_500_INTERNAL_SERVER_ERROR
)
def
index
(
request
):
return
render
(
request
,
'chat/index.html'
,
{})
def
room
(
request
,
room_name
):
return
render
(
request
,
'chat/room.html'
,
{
'room_name_json'
:
mark_safe
(
json
.
dumps
(
room_name
))
})
\ No newline at end of file
app/applicationlayer/urls.py
View file @
fe520cc9
...
...
@@ -5,6 +5,8 @@ from app.applicationlayer.management.company.views import CompanyViewSet
from
app.applicationlayer.management.department.views
import
DepartmentViewSet
from
app.applicationlayer.management.module.views
import
ModuleViewSet
# from app.applicationlayer.management.user.views import UsersManagementViewSet
from
app.applicationlayer.management.notification.views
import
NotificationsViewset
router
=
routers
.
DefaultRouter
()
...
...
@@ -13,6 +15,8 @@ router.register(r'companies', CompanyViewSet)
router
.
register
(
r'departments'
,
DepartmentViewSet
)
router
.
register
(
r'modules'
,
ModuleViewSet
)
# router.register(r'users', UsersManagementViewSet)
router
.
register
(
r'notifications'
,
NotificationsViewset
)
urlpatterns
=
(
path
(
''
,
include
(
router
.
urls
)),
...
...
app/entities/enums.py
View file @
fe520cc9
...
...
@@ -29,6 +29,7 @@ class GenerateCode(Enum):
COMPANY
=
'COMPANY'
DEPARTMENT
=
'DEPARTMENT'
USER
=
'USER'
NOTIFICATION
=
'NOTIF'
'''
...
...
@@ -66,3 +67,14 @@ class LogEntitiesEnum(Enum):
# STOCK = "Stock"
# STOCK_ITEM = "Stock Item"
# REQUISITION = "Requisition Header"
'''
*********
NOTIFICATION ENUMS
*********
'''
class
NotifTypeEnum
(
Enum
):
REMINDER
=
"REMINDER"
ACTIVITY
=
"ACTIVITY"
TASK
=
"TASK"
\ No newline at end of file
app/entities/migrations/0002_notification.py
0 → 100644
View file @
fe520cc9
# Generated by Django 2.2 on 2019-09-03 16:14
from
django.conf
import
settings
from
django.db
import
migrations
,
models
import
django.db.models.deletion
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'entities'
,
'0001_initial'
),
]
operations
=
[
migrations
.
CreateModel
(
name
=
'Notification'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
verbose_name
=
'ID'
)),
(
'code'
,
models
.
CharField
(
max_length
=
255
,
unique
=
True
)),
(
'form_header_code'
,
models
.
CharField
(
blank
=
True
,
max_length
=
255
,
null
=
True
)),
(
'notif_type'
,
models
.
CharField
(
choices
=
[(
'REMINDER'
,
'REMINDER'
),
(
'ACTIVITY'
,
'ACTIVITY'
),
(
'TASK'
,
'TASK'
)],
default
=
'TASK'
,
max_length
=
20
)),
(
'message'
,
models
.
CharField
(
blank
=
True
,
max_length
=
255
,
null
=
True
)),
(
'is_read'
,
models
.
BooleanField
(
default
=
False
,
null
=
True
)),
(
'created'
,
models
.
DateTimeField
(
auto_now_add
=
True
)),
(
'modified'
,
models
.
DateTimeField
(
auto_now
=
True
)),
(
'app_code'
,
models
.
ForeignKey
(
on_delete
=
django
.
db
.
models
.
deletion
.
DO_NOTHING
,
to
=
'entities.Application'
,
to_field
=
'code'
)),
(
'receiver_account_no'
,
models
.
ForeignKey
(
on_delete
=
django
.
db
.
models
.
deletion
.
DO_NOTHING
,
related_name
=
'receiver_account_no'
,
to
=
settings
.
AUTH_USER_MODEL
,
to_field
=
'code'
)),
(
'sender_account_no'
,
models
.
ForeignKey
(
on_delete
=
django
.
db
.
models
.
deletion
.
DO_NOTHING
,
related_name
=
'sender_account_no'
,
to
=
settings
.
AUTH_USER_MODEL
,
to_field
=
'code'
)),
],
options
=
{
'db_table'
:
'notifications'
,
},
),
]
app/entities/migrations/0003_auto_20190903_1725.py
0 → 100644
View file @
fe520cc9
# Generated by Django 2.2 on 2019-09-03 17:25
from
django.db
import
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'entities'
,
'0002_notification'
),
]
operations
=
[
migrations
.
RenameField
(
model_name
=
'notification'
,
old_name
=
'receiver_account_no'
,
new_name
=
'account_no'
,
),
migrations
.
RenameField
(
model_name
=
'notification'
,
old_name
=
'app_code'
,
new_name
=
'app'
,
),
]
app/entities/models.py
View file @
fe520cc9
...
...
@@ -323,3 +323,40 @@ class EntityLog(AuditClass):
class
Meta
:
db_table
=
'entity_logs'
"""
**********************
*** NOTIFICATION TABLES ***
**********************
"""
class
Notification
(
models
.
Model
):
code
=
models
.
CharField
(
unique
=
True
,
max_length
=
255
)
# primary key
form_header_code
=
models
.
CharField
(
max_length
=
255
,
null
=
True
,
blank
=
True
)
# form_header_code = models.ForeignKey(ChangeRequestFormHeader, on_delete=models.DO_NOTHING,
# to_field='code')
app
=
models
.
ForeignKey
(
Application
,
on_delete
=
models
.
DO_NOTHING
,
to_field
=
'code'
)
notif_type
=
models
.
CharField
(
choices
=
[(
tag
.
value
,
tag
.
value
)
for
tag
in
enums
.
NotifTypeEnum
],
default
=
enums
.
NotifTypeEnum
.
TASK
.
value
,
max_length
=
20
)
account_no
=
models
.
ForeignKey
(
User
,
on_delete
=
models
.
DO_NOTHING
,
to_field
=
'code'
,
related_name
=
'receiver_account_no'
)
message
=
models
.
CharField
(
max_length
=
255
,
null
=
True
,
blank
=
True
)
is_read
=
models
.
BooleanField
(
default
=
False
,
null
=
True
)
sender_account_no
=
models
.
ForeignKey
(
User
,
on_delete
=
models
.
DO_NOTHING
,
to_field
=
'code'
,
related_name
=
'sender_account_no'
)
created
=
models
.
DateTimeField
(
auto_now_add
=
True
)
modified
=
models
.
DateTimeField
(
auto_now
=
True
)
class
Meta
:
db_table
=
'notifications'
def
save
(
self
,
*
args
,
**
kwargs
):
super
(
Notification
,
self
)
.
save
(
*
args
,
**
kwargs
)
code
=
number_generator
(
enums
.
GenerateCode
.
NOTIFICATION
.
value
,
self
.
id
)
Notification
.
objects
.
filter
(
id
=
self
.
id
)
.
update
(
code
=
code
)
\ No newline at end of file
app/entities/templates/chat/index.html
0 → 100644
View file @
fe520cc9
<!-- chat/templates/chat/index.html -->
<!DOCTYPE html>
<html>
<head>
<meta
charset=
"utf-8"
/>
<title>
Chat Rooms
</title>
</head>
<body>
What chat room would you like to enter?
<br/>
<input
id=
"room-name-input"
type=
"text"
size=
"100"
/><br/>
<input
id=
"room-name-submit"
type=
"button"
value=
"Enter"
/>
<script>
document
.
querySelector
(
'
#room-name-input
'
).
focus
();
document
.
querySelector
(
'
#room-name-input
'
).
onkeyup
=
function
(
e
)
{
if
(
e
.
keyCode
===
13
)
{
// enter, return
document
.
querySelector
(
'
#room-name-submit
'
).
click
();
}
};
document
.
querySelector
(
'
#room-name-submit
'
).
onclick
=
function
(
e
)
{
var
roomName
=
document
.
querySelector
(
'
#room-name-input
'
).
value
;
window
.
location
.
pathname
=
'
/chat/
'
+
roomName
+
'
/
'
;
};
</script>
</body>
</html>
\ No newline at end of file
app/entities/templates/chat/room.html
0 → 100644
View file @
fe520cc9
<!-- chat/templates/chat/room.html -->
<!DOCTYPE html>
<html>
<head>
<meta
charset=
"utf-8"
/>
<title>
Chat Room
</title>
</head>
<body>
<textarea
id=
"chat-log"
cols=
"100"
rows=
"20"
></textarea><br/>
<input
id=
"chat-message-input"
type=
"text"
size=
"100"
/><br/>
<input
id=
"chat-message-submit"
type=
"button"
value=
"Send"
/>
</body>
<script>
var
roomName
=
{{
room_name_json
}};
var
chatSocket
=
new
WebSocket
(
'
ws://
'
+
window
.
location
.
host
+
'
/ws/chat/
'
+
roomName
+
'
/
'
);
chatSocket
.
onmessage
=
function
(
e
)
{
var
data
=
JSON
.
parse
(
e
.
data
);
var
message
=
data
[
'
message
'
];
document
.
querySelector
(
'
#chat-log
'
).
value
+=
(
message
+
'
\n
'
);
};
chatSocket
.
onclose
=
function
(
e
)
{
console
.
error
(
'
Chat socket closed unexpectedly
'
);
};
document
.
querySelector
(
'
#chat-message-input
'
).
focus
();
document
.
querySelector
(
'
#chat-message-input
'
).
onkeyup
=
function
(
e
)
{
if
(
e
.
keyCode
===
13
)
{
// enter, return
document
.
querySelector
(
'
#chat-message-submit
'
).
click
();
}
};
document
.
querySelector
(
'
#chat-message-submit
'
).
onclick
=
function
(
e
)
{
var
messageInputDom
=
document
.
querySelector
(
'
#chat-message-input
'
);
var
message
=
messageInputDom
.
value
;
chatSocket
.
send
(
JSON
.
stringify
({
'
message
'
:
message
}));
messageInputDom
.
value
=
''
;
};
</script>
</html>
\ No newline at end of file
config/routing.py
0 → 100644
View file @
fe520cc9
# mysite/routing.py
from
channels.auth
import
AuthMiddlewareStack
from
channels.routing
import
ProtocolTypeRouter
,
URLRouter
import
app.applicationlayer.management.notification.routing
application
=
ProtocolTypeRouter
({
# (http->django views is added by default)
'websocket'
:
AuthMiddlewareStack
(
URLRouter
(
app
.
applicationlayer
.
management
.
notification
.
routing
.
websocket_urlpatterns
)
),
})
\ No newline at end of file
config/settings/base.py
View file @
fe520cc9
...
...
@@ -44,7 +44,9 @@ INSTALLED_APPS = [
'rest_framework.authtoken'
,
'app.accesslayer'
,
'app.entities'
'app.entities'
,
'channels'
,
]
MIDDLEWARE
=
[
...
...
@@ -80,6 +82,17 @@ TEMPLATES = [
WSGI_APPLICATION
=
'config.wsgi.application'
ASGI_APPLICATION
=
"config.routing.application"
CHANNEL_LAYERS
=
{
'default'
:
{
'BACKEND'
:
'channels_redis.core.RedisChannelLayer'
,
'CONFIG'
:
{
"hosts"
:
[(
'127.0.0.1'
,
6379
)],
},
},
}
AUTH_USER_MODEL
=
'entities.User'
# Password validation
...
...
config/settings/local.py
View file @
fe520cc9
...
...
@@ -25,3 +25,5 @@ SESSION_TIMEOUT = config['LOCAL']['SESSION_TIMEOUT']
FRONT_END_URL
=
config
[
'LOCAL'
][
'FRONT_END_URL'
]
AUTH_ACCESSS_TOKEN_TIMEOUT
=
config
[
'LOCAL'
][
'AUTH_ACCESSS_TOKEN_TIMEOUT'
]
USER_DEFAULT_PASSWORD
=
config
[
'LOCAL'
][
'USER_DEFAULT_PASSWORD'
]
REALTIMESERVER_IP
=
config
[
'NOTIFICATION'
][
'REALTIMESERVER_IP'
]
\ No newline at end of file
config/urls.py
View file @
fe520cc9
...
...
@@ -15,6 +15,9 @@ Including another URLconf
"""
from
django.contrib
import
admin
from
django.urls
import
path
,
include
from
django.conf.urls
import
url
from
app.applicationlayer.management.notification
import
views
as
notifview
urlpatterns
=
[
# path('admin/', admin.site.urls),
...
...
@@ -22,4 +25,7 @@ urlpatterns = [
path
(
'api/v1/auth/'
,
include
(
'app.accesslayer.urls'
)),
path
(
'api/v1/'
,
include
(
'app.applicationlayer.urls'
)),
url
(
r'^chat/$'
,
notifview
.
index
,
name
=
'index'
),
url
(
r'^chat/(?P<room_name>[^/]+)/$'
,
notifview
.
room
,
name
=
'room'
),
]
env.template.ini
View file @
fe520cc9
...
...
@@ -46,5 +46,8 @@ FRONT_END_URL =
AUTH_ACCESSS_TOKEN_TIMEOUT = 3600
USER_DEFAULT_PASSWORD
=
password
[NOTIFICATION]
REALTIMESERVER_IP
=
127.0.0.1:8000
[SETTINGS]
CONFIG
=
config.settings.local
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment