init repository

master/v0.1.0
TBS093A 2020-05-07 09:10:05 +02:00
commit 5f2472a11f
71 changed files with 1582 additions and 0 deletions

View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,12 @@
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import chat.routing
application = ProtocolTypeRouter({
# (http->django views is added by default)
'websocket': AuthMiddlewareStack(
URLRouter(
chat.routing.websocket_urlpatterns
)
),
})

View File

@ -0,0 +1,144 @@
"""
Django settings for TradeApp project.
Generated by 'django-admin startproject' using Django 2.2.6.
For more information on this file, see
https://docs.djangoproject.com/en/2.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.2/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = ')o!ecewa-#m^$l$qy*pb)l&$swgt*xx8#j#hm3&2%^t#w-tqwu'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'generalApp',
'chat',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',
'channels'
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.BrokenLinkEmailsMiddleware',
'django.middleware.common.CommonMiddleware',
]
CORS_ORIGIN_ALLOW_ALL = True
# CORS_ORIGIN_ALLOW_ALL = False
#
# CORS_ORIGIN_WHITELIST = (
# 'http//:localhost:8000',
# )
ROOT_URLCONF = 'TradeApp.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'TradeApp.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Routing for channels websocket
ASGI_APPLICATION = "TradeApp.routing.application"
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 6379)],
},
},
}
# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
STATIC_URL = '/static/'

23
TradeApp/urls.py 100644
View File

@ -0,0 +1,23 @@
"""TradeApp URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('index/', include('generalApp.urls')),
path('chat/', include('chat.urls')),
path('admin/', admin.site.urls),
]

16
TradeApp/wsgi.py 100644
View File

@ -0,0 +1,16 @@
"""
WSGI config for TradeApp project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'TradeApp.settings')
application = get_wsgi_application()

0
chat/__init__.py 100644
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

4
chat/admin.py 100644
View File

@ -0,0 +1,4 @@
from django.contrib import admin
from .models import *
admin.site.register(Lobby)

61
chat/consumers.py 100644
View File

@ -0,0 +1,61 @@
from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
import json
from .models import Lobby
class ChatConsumer(WebsocketConsumer):
def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = f'chat_{self.room_name}'
checkSave = False
for lobby in Lobby.objects.all():
if lobby.name == self.room_name:
lobby.userCount = lobby.userCount + 1
Lobby.save(lobby)
checkSave = True
break
if checkSave == False:
lobbyRegister = Lobby()
lobbyRegister.name= self.room_name
lobbyRegister.userCount = 1
Lobby.save(lobbyRegister)
async_to_sync(self.channel_layer.group_add)(
self.room_group_name,
self.channel_name
)
self.accept()
def disconnect(self, close_code):
updateCountOfUsers = Lobby.objects.get(name = self.room_name)
updateCountOfUsers.userCount = updateCountOfUsers.userCount - 1
if updateCountOfUsers.userCount == 0:
Lobby.delete(updateCountOfUsers)
else:
Lobby.save(updateCountOfUsers)
async_to_sync(self.channel_layer.group_discard)(
self.room_group_name,
self.channel_name
)
def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json
async_to_sync(self.channel_layer.group_send)(
self.room_group_name,
{
'type': 'chat_message',
'message': message
}
)
def chat_message(self, event):
message = event['message']
# Send message to WebSocket
self.send(text_data=json.dumps(message))

View File

@ -0,0 +1,22 @@
# Generated by Django 2.2.6 on 2020-05-01 15:30
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Lobby',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=30)),
('userCount', models.IntegerField()),
],
),
]

View File

25
chat/models.py 100644
View File

@ -0,0 +1,25 @@
from django.db import models
from django.http import HttpResponse
import json
class Lobby(models.Model):
name = models.CharField(max_length=30)
userCount = models.IntegerField()
def __str__(self):
return f"{self.id} {self.name} {self.userCount}"
def fromDict(self, dict):
self.__dict__.update(dict)
def toDict(self):
return {"id": self.id,
"name": self.name,
"userCount": self.userCount}
def allObjectsDict(self):
objectAll = self.objects.all()
list = []
for x in objectAll:
list.append(x.toDict())
return json.dumps(list)

7
chat/routing.py 100644
View File

@ -0,0 +1,7 @@
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/(?P<room_name>[^/]+)/$', consumers.ChatConsumer),
]

8
chat/urls.py 100644
View File

@ -0,0 +1,8 @@
from django.urls import path
from . import views
urlpatterns = [
path('', views.chatIndex),
path('<slug:roomName>', views.chatConnect)
]

18
chat/views.py 100644
View File

@ -0,0 +1,18 @@
from django.http import HttpResponse
from .models import Lobby
import json
# REST Definition
def chatIndex(request):
if request.method == 'GET':
return HttpResponse(Lobby.allObjectsDict(Lobby))
if request.method == 'POST':
Lobby.save(json.load(request))
def chatConnect(request, roomName):
if request.method == 'GET':
return HttpResponse(f'connect to {roomName}')
if request.method == 'DELETE':
return HttpResponse('leave the chatroom')

BIN
db.sqlite3 100644

Binary file not shown.

View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,14 @@
from django.contrib import admin
from .models import *
admin.site.register(Users)
admin.site.register(Threads)
admin.site.register(Subjects)
admin.site.register(Comments)
admin.site.register(Ratings)
admin.site.register(Transactions)
admin.site.register(Triggers)
admin.site.register(Notifications)
# login: Admin
# password: Admin

View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class GeneralappConfig(AppConfig):
name = 'generalApp'

View File

@ -0,0 +1,122 @@
from django.http import HttpResponse
from datetime import datetime
from .models import *
from .utilities import *
import threading
import requests
import json
import os
class ExchangeVO():
triggerList = None
def __init__(self):
pass
@classmethod
def checkTrigger(self):
triggerAll = Triggers.objects.filter(status = 1).values("id", "user_id", "status", "course_values_for_trigger", "date_of_trigger")
self.triggerList = []
for x in triggerAll:
self.triggerList.append(x)
actualGraph = self.refreshGraph(1800)
for candle in actualGraph['candles']:
candleDate = datetime.strptime(candle['Date'], "%Y-%m-%d %H:%M:%S")
inArea = 0
for trigger in self.triggerList:
triggerDate = datetime.strptime(trigger['date_of_trigger'], "%Y-%d-%m %H:%M")
if int(trigger['course_values_for_trigger']) > int(candle['Min']) and triggerDate < candleDate:
inArea += 1
if int(trigger['course_values_for_trigger']) < int(candle['Max']) and triggerDate < candleDate:
inArea += 1
if inArea == 2:
disableTrigger = Triggers.objects.get(id = int(trigger['id']))
disableTrigger.status = 0
message = f"Exchange got Your Trigger Value! \nTrigger Value: {trigger['course_values_for_trigger']} \nCandle Date: {candle['Date']}"
newNotification = Notifications(user_id = int(trigger['user_id']), message = message)
newNotification.save()
disableTrigger.save()
inArea = 0
print(self.triggerList)
@classmethod
def createActualPrognosis(self, request, time, price, privilige):
actualGraph = self.refreshGraph(time)
svg = []
svgAll = 0
volume = []
actualCourse = 0
for candle in actualGraph['candles']:
svg.append((float(candle['Close'] + candle['Open']) / 2))
volume.append(float(candle['Volume']))
actualCourse = float(candle['Close'])
datePayment = candle['Date']
if svgAll == 0:
svgAll = svgAll + svg[-1]
else:
svgAll = (svgAll + svg[-1]) / 2
onePercentOfActualCourse = actualCourse / 100
percentsFromPriceToCourse = price / onePercentOfActualCourse
onePercentOfSvgCourse = svgAll / 100
priceAfterCourse = percentsFromPriceToCourse * onePercentOfSvgCourse
difference = priceAfterCourse - price
percentDifference = difference / onePercentOfSvgCourse
data = {
"price" : price,
"price_forecast" : priceAfterCourse,
"percent_of_difference" : percentDifference,
"course_on_payment" : actualCourse,
"svg_of_all" : svgAll,
"date_of_transaction" : datePayment
}
return HttpResponse(json.dumps(data))
@classmethod
def refreshGraph(self, time):
graph = []
try:
graph = self.createGraph(time)
except:
currentDirectory = os.path.dirname(__file__)
jsonPath = os.path.join(currentDirectory, '../testGraph.txt')
with open(jsonPath) as graphJson:
graph = json.load(graphJson)
return self.createGraph(time)
@classmethod
def createGraph(self, time):
miliseconds = 1000
firstResult = int(datetime.now().timestamp() * miliseconds)
lastResult = firstResult - 100000 * (time * 2)
url = f"https://api.bitbay.net/rest/trading/candle/history/BTC-PLN/{time}?from={lastResult}&to={firstResult}"
querystring = {"from": f"{lastResult}","to": f"{firstResult}"}
exchangeGraph = requests.request("GET", url, params=querystring)
response = json.loads(exchangeGraph.text)
graph = { 'candles': [], 'candlesCount' : 0, 'graphMin': float(response['items'][0][1]['h']), 'graphMax': 0 }
for x in range(len(response['items'])):
graph['candles'].append({'Open': 0, 'Close': 0, 'Max': 0, 'Min': 0, 'Volume': 0, 'Date': 0 })
graph['candles'][x]['Open'] = float(response['items'][x][1]['o'])
graph['candles'][x]['Close'] = float(response['items'][x][1]['c'])
graph['candles'][x]['Max'] = float(response['items'][x][1]['h'])
graph['candles'][x]['Min'] = float(response['items'][x][1]['l'])
graph['candles'][x]['Volume'] = float(response['items'][x][1]['v'])
graph['candles'][x]['Date'] = str(datetime.fromtimestamp(int(response['items'][x][0])/1000.0))
if graph['candles'][x]['Min'] < graph['graphMin']:
graph['graphMin'] = graph['candles'][x]['Min']
if graph['candles'][x]['Max'] > graph['graphMax']:
graph['graphMax'] = graph['candles'][x]['Max']
graph['candlesCount'] = len(response['items']) - 1
return graph
@classmethod
def getGraphView(self, request, time):
graph = []
try:
graph = self.createGraph(time)
except:
currentDirectory = os.path.dirname(__file__)
jsonPath = os.path.join(currentDirectory, '../testGraph.txt')
with open(jsonPath) as graphJson:
graph = json.load(graphJson)
return HttpResponse(json.dumps(graph))

View File

@ -0,0 +1,166 @@
from django.http import HttpResponse
from django.db import connection
from .exchangeVO import *
from .utilities import *
from .models import *
import requests
import json
import time
# Exchange Asynchronic Notifications
@newThread
def checkTriggerNotification():
while True:
ExchangeVO.checkTrigger()
connection.close()
time.sleep(1800)
# Exchange POST Methods
def addTrigger(request, userID):
return Triggers.addObject(request, userID, 1)
def addTransaction(request, userID):
return Transactions.addObject(request, userID, 1)
def Prognosis(request, time, price):
return ExchangeVO.createActualPrognosis(request, time, price, 1)
# Exchange GET Methods
def getExchangeGraph(request, time):
return ExchangeVO.getGraphView(request, time)
def getTrigger(request, id):
return Triggers.getObject(request, id, 1)
def getTransaction(request, id):
return Transactions.getObject(request, id, 1)
def getUserTriggers(request, userID):
return Triggers.getObjectsByParentID(request, userID, 1)
def getUserTransactions(request, userID):
return Transactions.getObjectByParentID(request, userID, 1)
def getTriggersAll(request):
return Triggers.getAllObjects(request, 2)
def getTransactionsAll(request):
return Transactions.getAllObjects(request, 2)
def getUserNotifications(request, userID):
return Notifications.getObjectsByParentID(request, userID, 1)
# Exchange PUT Methods
def putTrigger(request, id):
return Triggers.putObject(request, id, 1)
def putTransaction(request, id):
return Transactions.putObject(request, id, 1)
# Exchange DELETE Methods
def deleteTrigger(request, id):
return Triggers.deleteObject(request, id, 1)
def deleteTransaction(request, id):
return Transactions.deleteObject(request, id, 1)
def deleteNotification(request, id):
return Notifications.deleteObject(request, id, 1)
# Forum POST Methods
def loginUser(request):
login = jsonLoad(request)
if login['login'] is not None and login['password'] is not None:
users = Users.objects.all()
for x in users:
if x.login == login['login']:
if checkPassHash(login['password'], x.password):
newSession = createSession(request, x.toDict())
return HttpResponse(json.dumps({ 'token': newSession }))
return HttpResponse("Login Failed")
def logoutUser(request):
return deleteSession(request)
def registerUser(request):
return Users.addObject(request, None, None)
def addThread(request):
return Threads.addObject(request, None, 2)
def addSubject(request, threadID):
return Subjects.addObject(request, threadID, 1)
def addComment(request, subjectID):
return Comments.addObject(request, subjectID, 1)
def addRating(request, commentID):
return Ratings.addObject(request, commentID, 1)
# Forum GET Methods
def getUser(request, id):
return Users.getObject(request, id, 2)
def getUsersAll(request):
return Users.getAllObjects(request, 2)
def getThreadsAll(request):
return Threads.getAllObjects(request, 1)
def getThreadSubjects(request, threadID):
return Subjects.getObjectsByParentID(request, threadID, 1)
def getSubjectComments(request, subjectID):
return Comments.getObjectsByParentID(request, subjectID, 1)
def getCommentRatings(request, commentID):
return Ratings.getObjectsByParentID(request, commentID, 1)
# Forum PUT Methods
def putUser(request, id):
return Users.putObject(request, id, 1)
def putThread(request, id):
return Threads.putObject(request, id, 2)
def putSubject(request, id):
return Subjects.putObject(request, id, 1)
def putComment(request, id):
return Comments.putObject(request, id, 1)
def putRating(request, id):
return Ratings.putObject(request, id, 1)
# Forum DELETE Methods
def deleteUser(request, id):
return Users.deleteObject(request, id, 1)
def deleteThread(request, id):
return Threads.deleteObject(request, id, 2)
def deleteSubject(request, id):
return Subjects.deleteObject(request, id, 1)
def deleteComment(request, id):
return Comments.deleteObject(request, id, 1)
def deleteRating(request, id):
return Ratings.deleteObject(request, id, 1)

View File

@ -0,0 +1,110 @@
# Generated by Django 2.2.6 on 2019-12-19 16:17
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Comments',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('text', models.CharField(max_length=255)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Users',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('login', models.CharField(max_length=30)),
('password', models.CharField(max_length=30)),
('email', models.EmailField(max_length=50)),
('privilige', models.IntegerField(default=1)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Triggers',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('course_values_for_trigger', models.FloatField(default=255)),
('date_of_trigger', models.DateTimeField(verbose_name='date of trigger')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='generalApp.Users')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Transactions',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('price', models.FloatField(default=255)),
('price_forecast', models.FloatField(default=255)),
('currency', models.CharField(max_length=255)),
('date_of_transaction', models.DateTimeField(verbose_name='date of transaction')),
('course_on_payment', models.FloatField(default=255)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='generalApp.Users')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Threads',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=30)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='generalApp.Users')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Subjects',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=30)),
('thread', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='generalApp.Threads')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='generalApp.Users')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Ratings',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('value', models.IntegerField()),
('comment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='generalApp.Comments')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='generalApp.Users')),
],
options={
'abstract': False,
},
),
migrations.AddField(
model_name='comments',
name='subject',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='generalApp.Subjects'),
),
migrations.AddField(
model_name='comments',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='generalApp.Users'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.6 on 2019-12-29 13:52
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('generalApp', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='triggers',
name='status',
field=models.IntegerField(default=1),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.6 on 2019-12-29 14:07
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('generalApp', '0002_triggers_status'),
]
operations = [
migrations.AlterField(
model_name='triggers',
name='date_of_trigger',
field=models.CharField(max_length=255),
),
]

View File

@ -0,0 +1,25 @@
# Generated by Django 2.2.6 on 2019-12-29 15:59
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('generalApp', '0003_auto_20191229_1407'),
]
operations = [
migrations.CreateModel(
name='Notifications',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('message', models.CharField(max_length=255)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='generalApp.Users')),
],
options={
'abstract': False,
},
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.6 on 2020-01-03 16:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('generalApp', '0004_notifications'),
]
operations = [
migrations.AddField(
model_name='users',
name='avatar',
field=models.CharField(default='none', max_length=255),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.6 on 2020-01-13 21:47
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('generalApp', '0005_users_avatar'),
]
operations = [
migrations.AlterField(
model_name='comments',
name='text',
field=models.CharField(max_length=1000),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.6 on 2020-01-15 17:43
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('generalApp', '0006_auto_20200113_2147'),
]
operations = [
migrations.AlterField(
model_name='users',
name='password',
field=models.CharField(max_length=200),
),
]

View File

View File

@ -0,0 +1,350 @@
from django.db import models
from django.http import HttpResponse
from django.db.models import Avg
from datetime import datetime
from .utilities import *
class ObjectAbstract(models.Model):
@classmethod
def addObject(self, request, parentID, privilige):
if self.modelIsUser(self) or checkSession(request, privilige):
object = jsonLoad(request)
if self.modelIsUser(self):
object['privilige'] = 1
object['password'] = createPassHash(object['password'])
if self.checkUniqueValues(self, parentID, object):
return self.saveObject(self, parentID, object)
else:
return HttpResponse("Object Is Already Exist")
else:
return HttpResponse("No Permission")
def modelIsUser(model):
return model == Users
def checkUniqueValues(model, parentID, objectDict):
objectsAll = model.allObjectsDict(model)
for x in objectsAll:
if model == Users:
if x['login'].upper() == objectDict['login'].upper():
return False
elif model == Threads:
if x['name'].upper() == objectDict['name'].upper():
return False
elif model == Ratings:
if int(x['user_id']) == int(objectDict['user_id']) and int(x['comment_id']) == parentID:
return False
return True
def allObjectsDict(model):
objectAll = model.objects.all()
list = []
for x in objectAll:
list.append(x.toDict())
return list
def modelIsNotUser(model):
return model != Users
def saveObject(model, parentID, objectDict):
newObject = model()
newObject.fromDict(objectDict)
if model.modelHaveParent(model):
newObject.setParentID(parentID)
if model.modelIsTrigger(model):
newObject.setActualTime()
newObject.save()
if model.modelIsSubject(model) and model.newCommentInNewSubject(objectDict):
newComment = Comments(subject = newObject)
newComment.fromDict(objectDict['comment'])
newComment.save()
return HttpResponse(f"{model.__name__}/{Comments}: Add new Objects: {newObject.toDict()} and {newComment.toDict()}")
return HttpResponse(f"{model.__name__}: Add new Object: {newObject.toDict()}")
def modelHaveParent(model):
return model != Threads and model != Users
def modelIsTrigger(model):
return model == Triggers
def modelIsSubject(model):
return model == Subjects
def newCommentInNewSubject(objectDict):
return 'comment' in objectDict
@classmethod
def getObject(self, request, objectID, privilige):
return self.getObjectNormal(self, objectID)
def getObjectNormal(model, objectID):
object = model.objects.get(pk = objectID).toDict()
return HttpResponse(json.dumps(object))
@classmethod
def getAllObjects(self, request, privilige):
objectsAll = self.allObjectsDict(self)
return HttpResponse(json.dumps(objectsAll))
@classmethod
def getObjectsByParentID(self, request, parentID, privilige):
if self.modelHaveParent(self):
return HttpResponse(self.getAllByParentID(parentID))
return HttpResponse("No Permission")
@classmethod
def putObject(self, request, objectID, privilige):
if checkSession(request, privilige):
object = jsonLoad(request)
return self.updateObject(self, request, object, objectID)
else:
return HttpResponse("No Permission")
def updateObject(model, request, objectDict, objectID):
objectOld = model.objects.get(pk = objectID)
if model.modelIsUser(model):
if checkPassHash(objectDict['passwordOld'], objectOld.password):
if 'passwordNew' in objectDict.keys():
objectDict['password'] = createPassHash(objectDict['passwordNew'])
else:
return HttpResponse('Bad Password')
objectOld.fromDict(objectDict)
if checkUserPermission(objectOld.toDict(), request):
objectOld.save()
return HttpResponse(f"{model.__name__}: {objectOld.toDict()} has been updated")
else:
return HttpResponse("No Permission")
@classmethod
def deleteObject(self, request, objectID, privilige):
if checkSession(request, privilige):
objectDel = self.objects.get(pk = objectID)
if checkUserPermission(objectDel.toDict(), request):
if self.modelIsUser(self):
if checkPassHash(objectDict['password'], objectDel.password):
pass
else:
return HttpResponse("Bad Password")
objectDel.delete()
return HttpResponse(f"{self.__name__}: {objectDel} has been deleted")
else:
return HttpResponse("No Permission")
else:
return HttpResponse("No Permission")
class Meta:
abstract = True
class Users(ObjectAbstract):
login = models.CharField(max_length=30)
password = models.CharField(max_length=200)
email = models.EmailField(max_length=50)
avatar = models.CharField(max_length=255, default='none')
privilige = models.IntegerField(default=1)
def __str__(self):
return f"{self.id} {self.login}"
def fromDict(self, dict):
self.__dict__.update(dict)
def toDict(self):
return {"id": self.id,
"login": self.login,
"avatar": self.avatar,
"email": self.email,
"privilige": self.privilige}
class Threads(ObjectAbstract):
name = models.CharField(max_length=30)
user = models.ForeignKey(Users, on_delete = models.CASCADE)
def __str__(self):
return self.name
def fromDict(self, dict):
self.__dict__.update(dict)
def toDict(self):
return {"id": self.id,
"name": self.name,
"user_id": self.user.id,
"moderator": self.user.login,
"moderator_avatar": self.user.avatar,
"moderator_privilige": self.user.privilige}
class Subjects(ObjectAbstract):
name = models.CharField(max_length=30)
user = models.ForeignKey(Users, on_delete = models.CASCADE)
thread = models.ForeignKey(Threads, on_delete = models.CASCADE)
def __str__(self):
return f"{self.id} {self.name}"
def setParentID(self, parentID):
self.__dict__.update({ "thread_id": parentID })
@classmethod
def getAllByParentID(self, parentID):
list = [ x.toDict() for x in self.objects.filter(thread_id = parentID)]
return json.dumps(list)
def fromDict(self, dict):
self.__dict__.update(dict)
def toDict(self):
return {"id": self.id,
"name": self.name,
"user_id": self.user.id,
"author": self.user.login,
"author_avatar": self.user.avatar,
"author_privilige": self.user.privilige,
"thread_id": self.thread.id,
"thread_name": self.thread.name}
class Comments(ObjectAbstract):
text = models.CharField(max_length=1000)
user = models.ForeignKey(Users, on_delete = models.CASCADE)
subject = models.ForeignKey(Subjects, on_delete = models.CASCADE)
def __str__(self):
return f"{self.user} -> {self.subject}"
def setParentID(self, parentID):
self.__dict__.update({ "subject_id": parentID })
@classmethod
def getAllByParentID(self, parentID):
list = [ x.toDict() for x in self.objects.filter(subject_id = parentID)]
return json.dumps(list)
def commentSVG(self):
return
def fromDict(self, dict):
self.__dict__.update(dict)
def toDict(self):
return {"id": self.id,
"text": self.text,
"ratings_avg": Ratings.objects.filter(comment_id = self.id).aggregate(Avg('value')),
"user_id": self.user.id,
"author": self.user.login,
"author_avatar": self.user.avatar,
"author_privilige": self.user.privilige,
"subject_id": self.subject.id,
"subject_name": self.subject.name}
class Ratings(ObjectAbstract):
value = models.IntegerField()
user = models.ForeignKey(Users, on_delete = models.CASCADE)
comment = models.ForeignKey(Comments, on_delete = models.CASCADE)
def __str__(self):
return f"{self.user}, value: {self.value} -> comment in: {self.comment.subject}"
def setParentID(self, parentID):
self.__dict__.update({ "comment_id": parentID })
@classmethod
def getAllByParentID(self, parentID):
list = [ x.toDict() for x in self.objects.filter(comment_id = parentID)]
return json.dumps(list)
def fromDict(self, dict):
self.__dict__.update(dict)
def toDict(self):
return {"id": self.id,
"value": self.value,
"user_id": self.user.id,
"author": self.user.login,
"author_avatar": self.user.avatar,
"comment_id": self.comment.id,
"subject": self.comment.subject.name}
class Transactions(ObjectAbstract):
price = models.FloatField(default=255)
price_forecast = models.FloatField(default=255)
currency = models.CharField(max_length=255)
date_of_transaction = models.DateTimeField('date of transaction')
course_on_payment = models.FloatField(default=255)
user = models.ForeignKey(Users, on_delete = models.CASCADE)
def __str__(self):
return f"{self.user.login}, cash: {self.price}, prognosis: {self.price_forecast}"
def setParentID(self, parentID):
self.__dict__.update({ "user_id": parentID })
@classmethod
def getAllByParentID(self, parentID):
list = [ x.toDict() for x in self.objects.filter(user_id = parentID)]
return json.dumps(list)
def fromDict(self, dict):
self.__dict__.update(dict)
def toDict(self):
return {"id": self.id,
"price": self.price,
"currency": self.currency,
"date_of_transaction": self.date_of_transaction,
"course_on_payment": self.course_on_payment,
"user_id": self.user.id,
"author": self.user.login,
"exchange_id": self.exchange.id}
class Triggers(ObjectAbstract):
course_values_for_trigger = models.FloatField(default=255)
date_of_trigger = models.CharField(max_length=255)
status = models.IntegerField(default=1)
user = models.ForeignKey(Users, on_delete = models.CASCADE)
def __str__(self):
return f"{self.user.login}, trigger value: {self.course_values_for_trigger}, date: {self.date_of_trigger}"
def setParentID(self, parentID):
self.__dict__.update({ "user_id": parentID })
@classmethod
def getAllByParentID(self, parentID):
list = [ x.toDict() for x in self.objects.filter(user_id = parentID)]
return json.dumps(list)
def fromDict(self, dict):
self.__dict__.update(dict)
def toDict(self):
return {"id": self.id,
"course_values_for_trigger": self.course_values_for_trigger,
"date_of_trigger": self.date_of_trigger,
"status": self.status,
"user_id": self.user.id,
"author": self.user.login,}
def setActualTime(self):
self.date_of_trigger = str(datetime.now().strftime("%Y-%d-%m %H:%M"))
class Notifications(ObjectAbstract):
message = models.CharField(max_length=255)
user = models.ForeignKey(Users, on_delete = models.CASCADE)
def __str__(self):
return f"Message: {self.message}, for User: {self.user.login}"
def setParentID(self, parentID):
self.__dict__.update({ "user_id": parentID })
@classmethod
def getAllByParentID(self, parentID):
return json.dumps(list(self.objects.filter(user_id = parentID).values()))
def fromDict(self, dict):
self.__dict__.update(dict)
def toDict(self):
return {"id": self.id,
"message": self.message,
"user_id": self.user.id}

View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

30
generalApp/urls.py 100644
View File

@ -0,0 +1,30 @@
from django.urls import path
from . import views
urlpatterns = [
path('authUser', views.authUser),
path('user', views.users),
path('user/<int:id>', views.user),
path('thread', views.threads),
path('thread/<int:id>', views.thread),
path('thread/<int:threadID>/subject', views.subjects),
path('subject/<int:id>', views.subject),
path('subject/<int:subjectID>/comment', views.comments),
path('comment/<int:id>', views.comment),
path('comment/<int:commentID>/rating', views.ratings),
path('rating/<int:id>', views.rating),
path('exchange/<int:time>', views.exchangeGraph),
path('exchange/<int:time>/prognosis/<int:price>', views.exchangePrognosis),
path('user/<int:userID>/transaction', views.transactions),
path('transaction/<int:id>', views.transaction),
path('transaction/all', views.transactionsAll),
path('user/<int:userID>/trigger', views.triggers),
path('trigger/<int:id>', views.trigger),
path('trigger/all', views.triggersAll),
path('user/<int:userID>/notification', views.notifications),
path('notification/<int:id>', views.notification)
]

View File

@ -0,0 +1,121 @@
from hmac import compare_digest as checkHash
from django.http import HttpResponse
from threading import Thread
import threading
import requests
import crypt
import json
import jwt
# Session / Token Methods
tokenKey = 'U0VDUkVUX1BBU1NfQ0hFQ0s#!@#SDS!#'
tokens = []
def createSession(request, userDict):
newToken = createToken(userDict)
tokens.append(newToken)
return newToken
def createToken(userDict):
return jwt.encode( { 'payload': userDict }, tokenKey, algorithm = 'HS256' ).decode('UTF-8')
def checkSession(request, privilige):
token = tryGetTokenFromRequest(request)
for currentToken in tokens:
if token == currentToken:
if decodeToken(currentToken)['payload']['privilige'] >= privilige:
return True
else:
return False
return False
def tryGetTokenFromRequest(request):
try:
return jsonLoad(request)['token']
except:
pass
def decodeToken(token):
return jwt.decode( token, tokenKey, algorithms = ['HS256'] )
def checkUserPermission(modelDict, request):
def UserIsAdmin(token):
return decodeToken(token)['payload']['privilige'] == 3
def UserIsModer(token):
return decodeToken(token)['payload']['privilige'] == 2
def checkUserChanges(modelDict, token):
return decodeToken(token)['payload']['id'] == modelDict['user_id']
def checkUser(modelDict, token):
return decodeToken(token)['payload']['id'] == modelDict['id']
def modelIsNotUser(modelDict):
return 'user_id' in modelDict
def modelIsUser(modelDict):
return 'login' in modelDict
def checkCheats(modelDict, token):
if 'privilige' in modelDict:
if modelDict['privilige'] != decodeToken(token)['payload']['privilige']:
return True
else:
return False
else:
return False
token = tryGetTokenFromRequest(request)
if modelIsNotUser(modelDict):
if UserIsAdmin(token):
return True
elif UserIsModer(token):
return True
elif checkUserChanges(modelDict, token):
return True
else:
return False
elif modelIsUser(modelDict):
if UserIsAdmin(token):
return True
elif checkCheats(modelDict, token):
return False
elif checkUser(modelDict, token):
return True
else:
return False
def deleteSession(request):
token = jsonLoad(request)['token']
try:
tokens.remove(token)
return HttpResponse("Session Has Been Deleted")
except:
return HttpResponse("Session Delete Error")
# Security Hash / Crypt Methods
def createPassHash(password):
return crypt.crypt(password)
def checkPassHash(password, hashedPass):
return checkHash(hashedPass, crypt.crypt(password, hashedPass))
# Thread Method
def newThread(function):
def decorator(*args, **kwargs):
thread = Thread(target = function, args = args, kwargs = kwargs)
thread.daemon = True
thread.start()
return decorator
# JSON Load Method
def jsonLoad(self):
return json.loads(self.body.decode('utf-8'))

179
generalApp/views.py 100644
View File

@ -0,0 +1,179 @@
from django.http import HttpResponse
from .methods import *
# Threads Start
checkTriggerNotification()
# REST Definition
def authUser(request):
if request.method == 'POST':
return loginUser(request)
elif request.method == 'DELETE':
return logoutUser(request)
else:
return HttpResponse('Bad Request Method')
def users(request):
if request.method == 'GET':
return getUsersAll(request)
elif request.method == 'POST':
return registerUser(request)
else:
return HttpResponse('Bad Request Method')
def user(request, id):
if request.method == 'GET':
return getUser(request, id)
elif request.method == 'PUT':
return putUser(request, id)
elif request.method == 'DELETE':
return deleteUser(request, id)
else:
return HttpResponse('Bad Request Method')
def threads(request):
if request.method == 'GET':
return getThreadsAll(request)
elif request.method == 'POST':
return addThread(request)
else:
return HttpResponse('Bad Request Method')
def thread(request, id):
if request.method == 'PUT':
return putThread(request, id)
elif request.method == 'DELETE':
return deleteThread(request, id)
else:
return HttpResponse('Bad Request Method')
def subjects(request, threadID):
if request.method == 'GET':
return getThreadSubjects(request, threadID)
elif request.method == 'POST':
return addSubject(request, threadID)
else:
return HttpResponse('Bad Request Method')
def subject(request, id):
if request.method == 'PUT':
return putSubject(request, id)
elif request.method == 'DELETE':
return deleteSubject(request, id)
else:
return HttpResponse('Bad Request Method')
def comments(request, subjectID):
if request.method == 'GET':
return getSubjectComments(request, subjectID)
elif request.method == 'POST':
return addComment(request, subjectID)
else:
return HttpResponse('Bad Request Method')
def comment(request, id):
if request.method == 'PUT':
return putComment(request, id)
elif request.method == 'DELETE':
return deleteComment(request, id)
else:
return HttpResponse('Bad Request Method')
def ratings(request, commentID):
if request.method == 'GET':
return getCommentRatings(request, commentID)
elif request.method == 'POST':
return addRating(request, commentID)
else:
return HttpResponse('Bad Request Method')
def rating(request, id):
if request.method == 'PUT':
return putRating(request, id)
elif request.method == 'DELETE':
return deleteRating(request, id)
else:
return HttpResponse('Bad Request Method')
def exchangeGraph(request, time):
if request.method == 'GET':
return getExchangeGraph(request, time)
else:
return HttpResponse('Bad Request Method')
def exchangePrognosis(request, price, time):
if request.method == 'GET':
return Prognosis(request, time, price)
else:
return HttpResponse('Bad Request Method')
def transactions(request, userID):
if request.method == 'GET':
return getUserTransactions(request, userID)
elif request.method == 'POST':
return addTransaction(request, userID)
else:
return HttpResponse('Bad Request Method')
def transaction(request, id):
if request.method == 'GET':
return getTransaction(request, id)
elif request.method == 'PUT':
return putTransaction(request, id)
elif request.method == 'DELETE':
return deleteTransaction(request, id)
else:
return HttpResponse('Bad Request Method')
def transactionsAll(request):
if request.method == 'GET':
return getTransactionsAll(request)
else:
return HttpResponse('Bad Request Method')
def triggers(request, userID):
if request.method == 'GET':
return getUserTriggers(request, userID)
elif request.method == 'POST':
return addTrigger(request, userID)
else:
return HttpResponse('Bad Request Method')
def trigger(request, id):
if request.method == 'GET':
return getTrigger(request, id)
if request.method == 'PUT':
return putTrigger(request, id)
elif request.method == 'DELETE':
return deleteTrigger(request, id)
else:
return HttpResponse('Bad Request Method')
def triggersAll(request):
if request.method == 'GET':
return getTriggersAll(request)
else:
return HttpResponse('Bad Request Method')
def notifications(request, userID):
if request.method == 'GET':
return getUserNotifications(request, userID)
else:
return HttpResponse('Bad Request Method')
def notification(request, id):
if request.method == 'DELETE':
return deleteNotification(request, id)
else:
return HttpResponse('Bad Request Method')

21
manage.py 100755
View File

@ -0,0 +1,21 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'TradeApp.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()

4
run.sh 100755
View File

@ -0,0 +1,4 @@
sudo docker run -p 6379:6379 -d redis:5
python3 manage.py runserver 9090
exit $?

1
testGraph.txt 100644

File diff suppressed because one or more lines are too long

1
testGraph2.txt 100644

File diff suppressed because one or more lines are too long