-
Notifications
You must be signed in to change notification settings - Fork 3
[DRAFT] Adds serverlist api #93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
from datetime import timedelta | ||
|
||
from django.db import models | ||
from django.utils import timezone | ||
|
||
|
||
class Server(models.Model): | ||
name = models.CharField(max_length=100) | ||
ip_address = models.CharField(max_length=50) | ||
port = models.IntegerField() | ||
player_count = models.IntegerField() | ||
player_limit = models.IntegerField() | ||
image_link = models.URLField() | ||
round_time = models.TimeField() | ||
windows_build = models.URLField() | ||
linux_build = models.URLField() | ||
mac_build = models.URLField() | ||
build_version = models.CharField(max_length=16) | ||
code_scan_version = models.CharField(max_length=16) | ||
## TODO: ADD VALIDATION FOR APPROVED API KEYS SO THAT STRANGERS DONT SPAM STATIONHUB WITH INVALID SERVERS ## | ||
|
||
def __str__(self): | ||
return self.name | ||
|
||
def save(self, *args, **kwargs): | ||
self.updated_at = timezone.now() | ||
super().save(*args, **kwargs) | ||
|
||
def is_expired(self): | ||
expiration_time = self.updated_at + timedelta(seconds=10) | ||
return expiration_time < timezone.now() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from django.urls import path | ||
|
||
from .views import server_list | ||
|
||
urlpatterns = [ | ||
path("serverlist/", server_list, name="server_list"), | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import json | ||
|
||
from datetime import datetime | ||
|
||
from django.http import JsonResponse | ||
from django.views.decorators.csrf import csrf_exempt | ||
|
||
from .models import Server | ||
|
||
|
||
def server_list(request): | ||
servers = Server.objects.all() | ||
data = [] | ||
## TODO: ADD VALIDATION FOR APPROVED API KEYS SO THAT STRANGERS DONT SPAM STATIONHUB WITH INVALID SERVERS ## | ||
for server in servers: | ||
if server.is_expired(): | ||
server.delete() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems expensive to delete each one separately |
||
else: | ||
data.append( | ||
{ | ||
"name": server.name, | ||
"ip_address": server.ip_address, | ||
"port": server.port, | ||
"player_count": server.player_count, | ||
"image_link": server.image_link, | ||
} | ||
) | ||
return JsonResponse(data, safe=False) | ||
|
||
|
||
@csrf_exempt | ||
def add_server(request): | ||
if request.method != "POST": | ||
return JsonResponse({"error": "Only POST requests are allowed"}, status=405) | ||
try: | ||
server_validation = validate_server_info(request) | ||
if server_validation.status_code != 200: | ||
return server_validation | ||
data = json.loads(request.body) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. django doesn't have ability to create model from json? weird code |
||
name = data.get("name") | ||
ip_address = data.get("ip_address") | ||
port = data.get("port") | ||
player_count = data.get("player_count") | ||
player_limit = data.get("player_limit") | ||
image_link = data.get("image_link") | ||
windows_build = data.get("player_count") | ||
linux_build = data.get("player_count") | ||
mac_build = data.get("player_count") | ||
build_version = data.get("player_count") | ||
code_scan_version = data.get("player_count") | ||
|
||
existing_server = Server.objects.filter(name=name).first() | ||
if existing_server: | ||
# In case the server updates its info quickly before the 10 seconds pass, | ||
# we update everything while we're updating the experitation date as well | ||
existing_server.ip_address = ip_address | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is wrong because |
||
existing_server.port = port | ||
existing_server.player_count = player_count | ||
existing_server.player_limit = player_limit | ||
existing_server.image_link = image_link | ||
existing_server.windows_build = windows_build | ||
existing_server.linux_build = linux_build | ||
existing_server.mac_build = mac_build | ||
existing_server.build_version = build_version | ||
existing_server.code_scan_version = code_scan_version | ||
existing_server.updated_at = datetime.now() | ||
existing_server.save() | ||
else: | ||
Server.objects.create( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will error because |
||
name=name, | ||
ip_address=ip_address, | ||
port=port, | ||
player_count=player_count, | ||
image_link=image_link, | ||
updated_at=datetime.now(), | ||
) | ||
return JsonResponse({"success": "Server data added/updated successfully"}, status=200) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you don't need this json body |
||
except Exception as e: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. enormous kilometer wide try block |
||
return JsonResponse({"error": str(e)}, status=400) | ||
|
||
|
||
def validate_server_info(request): | ||
data = json.loads(request.body) | ||
name = data.get("name") | ||
ip_address = data.get("ip_address") | ||
port = data.get("port") | ||
windows_build = data.get("player_count") | ||
linux_build = data.get("player_count") | ||
mac_build = data.get("player_count") | ||
build_version = data.get("player_count") | ||
code_scan_version = data.get("player_count") | ||
|
||
if name is None or ip_address is None or port is None: | ||
return JsonResponse( | ||
{ | ||
"error": "Identifying server info are required, otherwise the server will not show up or be connectable on stationhub." | ||
}, | ||
status=400, | ||
) | ||
|
||
if ( | ||
windows_build is None | ||
or linux_build is None | ||
or mac_build is None | ||
or build_version is None | ||
or code_scan_version is None | ||
): | ||
return JsonResponse({"error": "Missing build information."}, status=400) | ||
|
||
return JsonResponse({"success": "Server info validated successfully"}, status=200) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you don't need this json body |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maximum length of a domain part is 63 characters, and an entire FQDN is 253. 50 could un-necessarily limit domains being used.
For example,
cpee0dbd14eedcc-cme0dbd14eedca.cpe.net.cable.rogers.com
is a real hostname (I found on Google) that measures >50 chars.