storing guilds first, then subscriptions

This commit is contained in:
Corban-Lee Jones 2024-04-02 17:28:42 +01:00
parent 73ee984747
commit 05e90c64e4
14 changed files with 383 additions and 304 deletions

View File

@ -4,7 +4,7 @@ import logging
from rest_framework import serializers from rest_framework import serializers
from apps.home.models import Subscription, TrackedContent from apps.home.models import Subscription, SavedGuilds
from apps.authentication.models import UserServerLink from apps.authentication.models import UserServerLink
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -106,16 +106,6 @@ class DynamicModelSerializer(serializers.ModelSerializer):
abstract = True abstract = True
# class SubscriptionTargetSerializer(DynamicModelSerializer):
# """
# Serializer for the Subscription Target Model.
# """
# class Meta:
# model = SubscriptionTarget
# fields = ("id", "creation_datetime")
class SubscriptionSerializer(DynamicModelSerializer): class SubscriptionSerializer(DynamicModelSerializer):
""" """
Serializer for the Subscription Model. Serializer for the Subscription Model.
@ -130,16 +120,6 @@ class SubscriptionSerializer(DynamicModelSerializer):
fields = ("uuid", "name", "rss_url", "image", "server", "targets", "creation_datetime", "extra_notes", "active") fields = ("uuid", "name", "rss_url", "image", "server", "targets", "creation_datetime", "extra_notes", "active")
class TrackedContentSerializer(DynamicModelSerializer):
"""
Serializer for the TrackedContent Model.
"""
class Meta:
model = TrackedContent
fields = ("uuid", "content_url", "subscription", "creation_datetime")
class UserServerLinkSerializer(DynamicModelSerializer): class UserServerLinkSerializer(DynamicModelSerializer):
""" """
Serializer for the UserServerLink Model. Serializer for the UserServerLink Model.
@ -148,3 +128,13 @@ class UserServerLinkSerializer(DynamicModelSerializer):
class Meta: class Meta:
model = UserServerLink model = UserServerLink
fields = ("id", "server_id", "user", "name", "icon", "icon_url", "permissions") fields = ("id", "server_id", "user", "name", "icon", "icon_url", "permissions")
class SavedGuildSerializer(DynamicModelSerializer):
"""
Serializer for the SavedGuild model.
"""
class Meta:
model = SavedGuilds
fields = ("id", "guild_id", "name", "icon")

View File

@ -6,13 +6,13 @@ from rest_framework.authtoken.views import obtain_auth_token
from .views import ( from .views import (
Subscription_ListView, Subscription_ListView,
Subscription_DetailView, Subscription_DetailView,
TrackedContent_ListView,
TrackedContent_DetailView,
UserServerLink_ListView, UserServerLink_ListView,
UserServerLink_DetailView UserServerLink_DetailView,
SavedGuild_ListView,
SavedGuild_DetailView
) )
urlpatterns = [ urlpatterns = [
path("api-auth/", include("rest_framework.urls", namespace="rest_framework")), path("api-auth/", include("rest_framework.urls", namespace="rest_framework")),
path("api-token-auth/", obtain_auth_token), path("api-token-auth/", obtain_auth_token),
@ -22,13 +22,13 @@ urlpatterns = [
path("<str:pk>/", Subscription_DetailView.as_view(), name="subscription-detail") path("<str:pk>/", Subscription_DetailView.as_view(), name="subscription-detail")
])), ])),
path("tracked/", include([
path("", TrackedContent_ListView.as_view(), name="tracked"),
path("<str:pk>/", TrackedContent_DetailView.as_view(), name="tracked-detail")
])),
path("serverlink/", include([ path("serverlink/", include([
path("", UserServerLink_ListView.as_view(), name="serverlink"), path("", UserServerLink_ListView.as_view(), name="serverlink"),
path("<int:pk>/", UserServerLink_DetailView.as_view(), name="serverlink-detail") path("<int:pk>/", UserServerLink_DetailView.as_view(), name="serverlink-detail")
])), ])),
path("saved-guilds/", include([
path("", SavedGuild_ListView.as_view(), name="saved-guilds"),
path("<int:pk>/", SavedGuild_DetailView.as_view(), name="saved-guilds-detail")
])),
] ]

View File

@ -11,12 +11,12 @@ from rest_framework.pagination import PageNumberPagination
from rest_framework.authentication import SessionAuthentication, TokenAuthentication from rest_framework.authentication import SessionAuthentication, TokenAuthentication
from rest_framework.parsers import MultiPartParser, FormParser from rest_framework.parsers import MultiPartParser, FormParser
from apps.home.models import Subscription, TrackedContent from apps.home.models import Subscription, SavedGuilds
from apps.authentication.models import UserServerLink from apps.authentication.models import UserServerLink
from .serializers import ( from .serializers import (
SubscriptionSerializer, SubscriptionSerializer,
TrackedContentSerializer, UserServerLinkSerializer,
UserServerLinkSerializer SavedGuildSerializer
) )
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -92,61 +92,6 @@ class Subscription_DetailView(generics.RetrieveUpdateDestroyAPIView):
# .order_by("-creation_datetime") # .order_by("-creation_datetime")
# =================================================================================================
# Tracked Content Views
class TrackedContent_ListView(generics.ListCreateAPIView):
"""
View to provide a list of TrackedContent model instances.
Can also be used to create a new instance.
Supports: GET, POST
"""
authentication_classes = [SessionAuthentication, TokenAuthentication]
permission_classes = [permissions.IsAuthenticated]
pagination_class = DefaultPagination
serializer_class = TrackedContentSerializer
queryset = TrackedContent.objects.all().order_by("-creation_datetime")
filter_backends = [filters.SearchFilter, rest_filters.DjangoFilterBackend, filters.OrderingFilter]
filterset_fields = ["uuid", "subscription", "content_url", "creation_datetime"]
search_fields = ["name"]
ordering_fields = ["creation_datetime"]
def post(self, request):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
try:
self.perform_create(serializer)
except IntegrityError:
return Response(
{"detail": "Tracked content must be unique"},
status=status.HTTP_409_CONFLICT,
exception=True
)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
class TrackedContent_DetailView(generics.RetrieveDestroyAPIView):
"""
View to provide details on a particular TrackedContent model instances.
Supports: GET, DELETE
"""
authentication_classes = [SessionAuthentication, TokenAuthentication]
permission_classes = [permissions.IsAuthenticated]
parser_classes = [MultiPartParser, FormParser]
serializer_class = TrackedContentSerializer
queryset = TrackedContent.objects.all().order_by("-creation_datetime")
# ================================================================================================= # =================================================================================================
# UserServerLinks Views # UserServerLinks Views
@ -224,3 +169,59 @@ class UserServerLink_DetailView(generics.RetrieveDestroyAPIView):
serializer_class = UserServerLinkSerializer serializer_class = UserServerLinkSerializer
queryset = UserServerLink.objects.all() queryset = UserServerLink.objects.all()
# =================================================================================================
# SavedGuild Views
class SavedGuild_ListView(generics.ListCreateAPIView):
"""
View to provide a list of SavedGuild model instances.
Can also be used to create a new instance.
Supports: GET, POST
"""
authentication_classes = [SessionAuthentication, TokenAuthentication]
permission_classes = [permissions.IsAuthenticated]
pagination_class = None
serializer_class = SavedGuildSerializer
filter_backends = [filters.SearchFilter, rest_filters.DjangoFilterBackend, filters.OrderingFilter]
filterset_fields = ["id", "guild_id", "name", "icon"]
search_fields = ["name"]
def get_queryset(self):
return SavedGuilds.objects.all()
def post(self, request):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
try:
self.perform_create(serializer)
except IntegrityError:
return Response(
{"detail": "SavedGuild must be unique"},
status=status.HTTP_409_CONFLICT,
exception=True
)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
class SavedGuild_DetailView(generics.RetrieveDestroyAPIView):
"""
View to provide details on a particular UserServerLink model instances.
Supports: GET, DELETE
"""
authentication_classes = [SessionAuthentication, TokenAuthentication]
permission_classes = [permissions.IsAuthenticated]
parser_classes = [MultiPartParser, FormParser]
serializer_class = SavedGuildSerializer
queryset = SavedGuilds.objects.all()

View File

@ -3,7 +3,7 @@
from django.urls import path from django.urls import path
from django.contrib.auth.views import LogoutView from django.contrib.auth.views import LogoutView
from .views import DiscordLoginAction, DiscordLoginRedirect, Login, GuildsView, GuildChannelsView from .views import DiscordLoginAction, DiscordLoginRedirect, Login, GuildsView, GuildChannelsView, SaveGuildView
urlpatterns = [ urlpatterns = [
@ -13,6 +13,7 @@ urlpatterns = [
path("logout/", LogoutView.as_view(), name="logout"), path("logout/", LogoutView.as_view(), name="logout"),
path("guilds/", GuildsView.as_view(), name="guilds"), path("guilds/", GuildsView.as_view(), name="guilds"),
path("channels/", GuildChannelsView.as_view(), name="channels") path("channels/", GuildChannelsView.as_view(), name="channels"),
path("save-guild/", SaveGuildView.as_view(), name="save-guild")
] ]

View File

@ -11,6 +11,7 @@ from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login from django.contrib.auth import authenticate, login
from .models import UserServerLink from .models import UserServerLink
from apps.home.models import SavedGuilds
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -97,35 +98,10 @@ class GuildsView(View):
) )
content = response.json() content = response.json()
self.create_server_links(request.user, content) print(response, content)
return JsonResponse(content, safe=False) return JsonResponse(content, safe=False)
def create_server_links(self, user, content: list[dict]):
"""
Creates objects representing the user's discord servers, storing
server info and the user's permissions within.
Parameters
----------
content : list[dict]
Raw data for the servers.
"""
servers = [
UserServerLink(
server_id=server["id"],
user=user,
name=server["name"],
permissions=server["permissions"],
icon=server["icon"]
)
for server in content
]
UserServerLink.objects.filter(user=user).delete()
UserServerLink.objects.bulk_create(servers)
class GuildChannelsView(View): class GuildChannelsView(View):
@ -139,5 +115,30 @@ class GuildChannelsView(View):
url=f"{settings.DISCORD_API_URL}/guilds/{guild_id}/channels", url=f"{settings.DISCORD_API_URL}/guilds/{guild_id}/channels",
headers={"Authorization": f"Bot {settings.BOT_TOKEN}"} headers={"Authorization": f"Bot {settings.BOT_TOKEN}"}
) )
print(response, response.json())
return JsonResponse(response.json(), safe=False) return JsonResponse(response.json(), safe=False)
class SaveGuildView(View):
def get(self, request, *args, **kwargs):
guild_id = request.GET.get("id")
if guild_id:
return SavedGuilds.objects.filter(id=guild_id)
return SavedGuilds.objects.all()
def post(self, request, *args, **kwargs):
data = request.POST
guild = SavedGuilds.objects.get_or_create(
id=data["id"],
name=data["name"],
icon=data["icon"]
)
return JsonResponse(data)

View File

@ -2,7 +2,7 @@
from django.contrib import admin from django.contrib import admin
from .models import Subscription, TrackedContent from .models import Subscription, SavedGuilds
@admin.register(Subscription) @admin.register(Subscription)
@ -13,17 +13,8 @@ class SubscriptionAdmin(admin.ModelAdmin):
] ]
# @admin.register(SubscriptionTarget) @admin.register(SavedGuilds)
# class SubscriptionTargetAdmin(admin.ModelAdmin): class SavedGuildAdmin(admin.ModelAdmin):
# list_display = [
# "id", "creation_datetime"
# ]
@admin.register(TrackedContent)
class TrackedContentAdmin(admin.ModelAdmin):
list_display = [ list_display = [
"uuid", "content_url", "subscription", "id", "name", "icon"
"creation_datetime"
] ]

View File

@ -0,0 +1,24 @@
# Generated by Django 5.0.1 on 2024-04-02 11:16
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('home', '0006_alter_subscription_image'),
]
operations = [
migrations.CreateModel(
name='SavedGuilds',
fields=[
('id', models.PositiveBigIntegerField(primary_key=True, serialize=False)),
('name', models.CharField(max_length=128)),
('icon', models.CharField(max_length=128)),
],
),
migrations.DeleteModel(
name='TrackedContent',
),
]

View File

@ -0,0 +1,24 @@
# Generated by Django 5.0.1 on 2024-04-02 16:12
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('home', '0007_savedguilds_delete_trackedcontent'),
]
operations = [
migrations.AddField(
model_name='savedguilds',
name='guild_id',
field=models.PositiveBigIntegerField(default=1),
preserve_default=False,
),
migrations.AlterField(
model_name='savedguilds',
name='id',
field=models.AutoField(primary_key=True, serialize=False),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 5.0.1 on 2024-04-02 16:25
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('home', '0008_savedguilds_guild_id_alter_savedguilds_id'),
]
operations = [
migrations.AlterField(
model_name='savedguilds',
name='guild_id',
field=models.CharField(max_length=128),
),
]

View File

@ -39,31 +39,26 @@ class IconPathGenerator:
return Path(instance.__class__.__name__.lower()) / str(instance.uuid) / "icon.webp" return Path(instance.__class__.__name__.lower()) / str(instance.uuid) / "icon.webp"
# class SubscriptionTarget(models.Model): class SavedGuilds(models.Model):
# """ """
# Represents a Discord TextChannel that should be subject to the content of a Subscription.
# """ """
# id = models.PositiveBigIntegerField( id = models.AutoField(
# verbose_name=_("id"), primary_key=True
# primary_key=True, )
# help_text=_("Discord Channel ID")
# )
# creation_datetime = models.DateTimeField( guild_id = models.CharField(
# verbose_name=_("creation datetime"), max_length=128
# help_text=_("when this instance was created."), )
# default=timezone.now,
# editable=False
# )
# class Meta: name = models.CharField(
# verbose_name = "subscription target" max_length=128
# verbose_name_plural = "subscription targets" )
# get_latest_by = "-creation_date"
# def __str__(self): icon = models.CharField(
# return str(self.id) max_length=128
)
class Subscription(models.Model): class Subscription(models.Model):
@ -155,126 +150,3 @@ class Subscription(models.Model):
log.debug("%sSubscription Saved %s", new_text, self.uuid) log.debug("%sSubscription Saved %s", new_text, self.uuid)
super().save(*args, **kwargs) super().save(*args, **kwargs)
# @property
# def channels(self):
# """
# Returns all SubscriptionChannel objects linked to this Subscription.
# """
# return SubscriptionChannel.objects.filter(subscription=self)
# def save(self, *args, **kwargs):
# if Subscription.objects.filter(server=self.server).count() >= 1:
# raise IntegrityError(f"Subscription limit reached for server '{self.server}'")
# super().save(*args, **kwargs)
# class SubscriptionChannel(models.Model):
# """
# Represents a Discord TextChannel that should be subject to the content of a Subscription.
# """
# uuid = models.UUIDField(
# primary_key=True,
# default=uuid4,
# editable=False
# )
# # The ID is not auto generated, but rather be obtained from discord.
# id = models.PositiveBigIntegerField(
# verbose_name=_("id"),
# help_text=_("Identifier of the channel, provided by Discord.")
# )
# subscription = models.ForeignKey(
# verbose_name=_("subscription"),
# help_text=_("The subscription of this instance."),
# to=Subscription,
# on_delete=models.CASCADE
# )
# creation_datetime = models.DateTimeField(
# verbose_name=_("creation datetime"),
# help_text=_("when this instance was created."),
# default=timezone.now,
# editable=False
# )
# class Meta:
# verbose_name = "subscription channel"
# verbose_name_plural = "subscription channels"
# get_latest_by = "-creation_date"
# constraints = [
# models.UniqueConstraint(fields=["id", "subscription"], name="unique id & sub pair")
# ]
# def __str__(self):
# return str(self.id)
# def save(self, *args, **kwargs):
# if SubscriptionChannel.objects.filter(subscription=self.subscription).count() >= 4:
# raise IntegrityError(
# f"SubscriptionChannel limit reached for subscription '{self.subscription}'"
# )
# super().save(*args, **kwargs)
class TrackedContent(models.Model):
"""
Tracks content shared from an RSS Feed Subscription.
Content is tracked to help prevent duplicate content.
"""
uuid = models.UUIDField(
primary_key=True,
default=uuid4,
editable=False
)
subscription = models.ForeignKey(
verbose_name=_("subscription"),
help_text=_("The subscription that this content originated from."),
to=Subscription,
on_delete=models.CASCADE,
related_name="tracked_content"
)
content_url = models.URLField(
verbose_name=_("content url"),
help_text=_("URL of the tracked content.")
)
creation_datetime = models.DateTimeField(
verbose_name=_("creation datetime"),
help_text=_("when this instance was created."),
default=timezone.now,
editable=False
)
def __str__(self):
return str(self.content_url)
@receiver(pre_save, sender=TrackedContent)
def maintain_item_cap(sender, instance, **kwargs):
""""
Delete the latest tracked content, if the total under
the same subscription reaches 100.
"""
log.debug("checking if tracked content can be deleted.")
queryset = sender.objects.filter(subscription=instance.subscription)
total_tracked = queryset.count()
if total_tracked < 100:
log.debug("tracked content cannot be deleted, less than 100 items: %s", total_tracked)
return
oldest = queryset.earliest()
log.info("tracked content limit exceeded, deleting oldest item with uuid: %s", oldest.uuid)
oldest.delete()

View File

@ -1,3 +1,59 @@
function getSavedGuilds() {
return new Promise(function(resolve, reject) {
$.ajax({
url: "/api/saved-guilds/",
type: "GET",
beforeSend: function(xhr) {
xhr.setRequestHeader("X-CSRFToken", CSRF_MiddlewareToken);
},
success: function(response) {
resolve(response);
},
error: function(response) {
reject(response);
}
});
});
}
function getSavedGuild(id) {
return new Promise(function(resolve, reject) {
$.ajax({
url: `/api/saved-guilds/${id}/`,
type: "GET",
beforeSend: function(xhr) {
xhr.setRequestHeader("X-CSRFToken", CSRF_MiddlewareToken);
},
success: function(response) {
resolve(response);
},
error: function(response) {
reject(response);
}
});
});
}
function newSavedGuild(formData) {
return new Promise(function(resolve, reject) {
$.ajax({
url: "/api/saved-guilds/",
type: "POST",
data: formData,
processData: false,
contentType: false,
beforeSend: function(xhr) {
xhr.setRequestHeader("X-CSRFToken", CSRF_MiddlewareToken);
},
success: function(response) {
resolve(response);
},
error: function(response) {
reject(response);
}
});
});
}
function getSubscriptions() { function getSubscriptions() {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {

View File

@ -74,7 +74,7 @@ function loadGuilds() {
for (i = 1; i < response.length; i++) { for (i = 1; i < response.length; i++) {
var guild = response[i]; var guild = response[i];
$("#editSubServer").append($("<option>", { $("#editSubServer").append($("<option>", {
value: guild.id, value: guild.guild_id,
text: guild.name text: guild.name
})); }));
} }

View File

@ -0,0 +1,19 @@
<form id="serverForm" novalidate>
<div class="modal fade" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
test
</div>
<div class="modal-body">
<select name="serverOptions" id="serverOptions" class="select-2" data-dropdownparent="#serverForm .modal"></select>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Submit</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
</form>

View File

@ -19,34 +19,9 @@
<div class="peers as-s ai-s w-100"> <div class="peers as-s ai-s w-100">
<div class="peer bg-body-secondary"> <div class="peer bg-body-secondary">
<div class="p-2 layers border-end h-100"> <div id="serverList" class="p-2 layers border-end h-100">
<div class="layer mb-2"> <div class="layer mb-2">
<button type="button" class="rounded-3 p-1 bg-body bd"> <button type="button" id="newServerBtn" class="btn btn-secondary rounded-3 p-1 bd" onclick="javascript: openServerModal();">
<img src="https://cdn.discordapp.com/icons/136501320340209664/bc41eb01d667196c17e05c045f357268.webp?size=80" alt="" width="50">
</button>
</div>
<div class="layer mb-2">
<button type="button" class="rounded-3 p-1 bg-body bd">
<img src="https://cdn.discordapp.com/icons/136501320340209664/bc41eb01d667196c17e05c045f357268.webp?size=80" alt="" width="50">
</button>
</div>
<div class="layer mb-2">
<button type="button" class="rounded-3 p-1 bg-body bd">
<img src="https://cdn.discordapp.com/icons/136501320340209664/bc41eb01d667196c17e05c045f357268.webp?size=80" alt="" width="50">
</button>
</div>
<div class="layer mb-2">
<button type="button" class="rounded-3 p-1 bg-body bd">
<img src="https://cdn.discordapp.com/icons/136501320340209664/bc41eb01d667196c17e05c045f357268.webp?size=80" alt="" width="50">
</button>
</div>
<div class="layer mb-2">
<button type="button" class="rounded-3 p-1 bg-body bd">
<img src="https://cdn.discordapp.com/icons/136501320340209664/bc41eb01d667196c17e05c045f357268.webp?size=80" alt="" width="50">
</button>
</div>
<div class="layer mb-2">
<button type="button" class="btn btn-secondary rounded-3 p-1 bd" onclick="javascript: alert('add new server (not implemented)');">
<span class="d-flex jc-c ai-c" style="width: 50px; height: 50px;"> <span class="d-flex jc-c ai-c" style="width: 50px; height: 50px;">
<i class="bi bi-plus-lg fs-4"></i> <i class="bi bi-plus-lg fs-4"></i>
</span> </span>
@ -55,7 +30,7 @@
</div> </div>
</div> </div>
<div class="peer-greed"> <div class="peer-greed">
<header class="px-4 py-3 bg-body-secondary"> <header class="px-4 py-3 border-bottom">
<div class="peers"> <div class="peers">
<div class="peer-greed"> <div class="peer-greed">
<div class="peers ai-c"> <div class="peers ai-c">
@ -69,7 +44,7 @@
</div> </div>
</div> </div>
<div class="peer d-flex as-s ai-c"> <div class="peer d-flex as-s ai-c">
<button type="button" class="btn btn-primary">New Subscription</button> <button type="button" id="newSubscriptionBtn" class="btn btn-primary">New Subscription</button>
</div> </div>
</div> </div>
</header> </header>
@ -115,7 +90,114 @@
</div> </div>
</main> </main>
{% include "home/includes/servermodal.html" %}
{% endblock content %} {% endblock content %}
<!-- Specific Page JS goes HERE --> <!-- Specific Page JS goes HERE -->
{% block javascripts %}{% endblock javascripts %} {% block javascripts %}
<script id="serverItemTemplate" type="text/template">
<div class="layer mb-2">
<button type="button" class="rounded-3 p-1 bg-body bd">
<img src="" class="rounded-3" alt="" width="50" height="50">
<!-- https://cdn.discordapp.com/icons/136501320340209664/bc41eb01d667196c17e05c045f357268.webp?size=80 -->
</button>
</div>
</script>
<script src="{% static 'js/api.js' %}"></script>
<script>
function openServerModal() {
$("#newServerBtn").prop("disabled", true);
$('#serverOptions').val(null).trigger('change');
$("#serverOptions").empty();
$.ajax({
url: "/guilds",
type: "GET",
success: function(response) {
for (i = 1; i < response.length; i++) {
var guild = response[i];
$("#serverOptions").append($("<option>", {
value: guild.id,
text: guild.name,
"data-icon": guild.icon
}));
}
$("#newServerBtn").prop("disabled", false);
$("#serverForm .modal").modal("show");
},
error: function(response) {
$("#newServerBtn").prop("disabled", false);
alert(JSON.stringify(response, null, 4));
}
});
};
function addServer(serverName, serverId, serverIconHash) {
var formData = new FormData();
formData.append("name", serverName);
formData.append("guild_id", serverId);
formData.append("icon", serverIconHash);
newSavedGuild(formData)
.then(resp => {
alert(JSON.stringify(resp, null, 4));
})
.catch(err => {
alert(JSON.stringify(err, null, 4));
})
addServerTemplate(serverId, serverIconHash);
}
$(document).ready(function() {
getSavedGuilds()
.then(resp => {
alert(JSON.stringify(resp, null, 4));
for (i=0; i < resp.length; i++) {
var guild = resp[i];
addServerTemplate(guild.guild_id, guild.icon);
}
})
.catch(err => {
alert(JSON.stringify(err, null, 4));
})
});
function addServerTemplate(serverId, serverIconHash) {
template = $($("#serverItemTemplate").html());
template.find("img").attr("src", `https://cdn.discordapp.com/icons/${serverId}/${serverIconHash}.webp?size=80`);
$("#serverList").prepend(template);
}
$("#serverForm").on("submit", function(event) {
event.preventDefault();
var selectedOption = $("#serverOptions option:selected");
serverName = selectedOption.text();
serverId = selectedOption.val();
serverIconHash = selectedOption.attr("data-icon");
addServer(serverName, serverId, serverIconHash);
// $.ajax({
// url: "",
// type: "GET",
// success: function(response) {
// alert(JSON.stringify(response, null, 4));
// },
// error: function(response) {
// alert(JSON.stringify(response, null, 4));
// }
// });
$("#serverForm .modal").modal("hide");
alert(`${serverName} ${serverId} ${serverIconHash}`);
});
</script>
{% endblock javascripts %}