Compare commits
No commits in common. "7887074b3d061bac2a42bf51a5f0d05a89faa6da" and "02950319d7e26ad96317e01790e666086fd90f7c" have entirely different histories.
7887074b3d
...
02950319d7
|
@ -0,0 +1,104 @@
|
||||||
|
import os
|
||||||
|
import discord
|
||||||
|
import discord.utils
|
||||||
|
import urllib.request, json
|
||||||
|
import asyncio
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
|
||||||
|
TOKEN = os.getenv('DISCORD_TOKEN')
|
||||||
|
GUILD = '42ctf'
|
||||||
|
|
||||||
|
intents = discord.Intents.all()
|
||||||
|
client = discord.Client(intents=intents)
|
||||||
|
|
||||||
|
db_file = open('members.json', 'r')
|
||||||
|
users = json.load(db_file)
|
||||||
|
db_file.close()
|
||||||
|
|
||||||
|
logging.basicConfig(filename='bot.log', format='%(asctime)s %(message)s', level=logging.INFO)
|
||||||
|
|
||||||
|
guild = ''
|
||||||
|
roles = {}
|
||||||
|
|
||||||
|
def get_rank(token):
|
||||||
|
url = urllib.request.urlopen("https://www.42ctf.org/accounts/rank/" + token)
|
||||||
|
data = json.loads(url.read().decode())
|
||||||
|
rank = data['rank']
|
||||||
|
return rank
|
||||||
|
|
||||||
|
async def watch_roles():
|
||||||
|
global users
|
||||||
|
await client.wait_until_ready() # ensures cache is loaded
|
||||||
|
while not client.is_closed():
|
||||||
|
for member_id, token in users.items():
|
||||||
|
if (token == "0000"):
|
||||||
|
continue
|
||||||
|
member = discord.utils.get(guild.members, id=int(member_id))
|
||||||
|
rank = get_rank(token)
|
||||||
|
if rank == 1 and roles['top1'] not in member.roles:
|
||||||
|
await member.add_roles(roles['top1'])
|
||||||
|
await member.remove_roles(roles['top10'])
|
||||||
|
await member.remove_roles(roles['top50'])
|
||||||
|
elif rank > 1 and rank <= 10 and roles['top10'] not in member.roles:
|
||||||
|
await member.add_roles(roles['top10'])
|
||||||
|
await member.remove_roles(roles['top1'])
|
||||||
|
await member.remove_roles(roles['top50'])
|
||||||
|
elif rank > 10 and rank <= 50 and roles['top50'] not in member.roles:
|
||||||
|
await member.add_roles(roles['top50'])
|
||||||
|
await member.remove_roles(roles['top10'])
|
||||||
|
await member.remove_roles(roles['top1'])
|
||||||
|
elif rank > 50:
|
||||||
|
await member.remove_roles(roles['top1'])
|
||||||
|
await member.remove_roles(roles['top10'])
|
||||||
|
await member.remove_roles(roles['top50'])
|
||||||
|
await asyncio.sleep(60)
|
||||||
|
|
||||||
|
@client.event
|
||||||
|
async def on_ready():
|
||||||
|
global guild, roles
|
||||||
|
guild = discord.utils.get(client.guilds, name=GUILD)
|
||||||
|
roles['top10'] = discord.utils.get(guild.roles, id=801787467064672286)
|
||||||
|
roles['top1'] = discord.utils.get(guild.roles, id=798638767359524875)
|
||||||
|
roles['top50'] = discord.utils.get(guild.roles, id=803729539145924649)
|
||||||
|
|
||||||
|
logging.info('%s is connected to the following guild: %s(id: %d)', client.user, guild.name, guild.id)
|
||||||
|
client.loop.create_task(watch_roles())
|
||||||
|
|
||||||
|
@client.event
|
||||||
|
async def on_message(message):
|
||||||
|
global guild, roles
|
||||||
|
|
||||||
|
if message.author == client.user:
|
||||||
|
return
|
||||||
|
|
||||||
|
if '!connect' in message.content:
|
||||||
|
try:
|
||||||
|
user_token = message.content.split(' ')[1]
|
||||||
|
member = discord.utils.get(guild.members, name=message.author.name)
|
||||||
|
rank = get_rank(user_token)
|
||||||
|
users[str(member.id)] = user_token
|
||||||
|
logging.info("MESSAGE: from %s with token %s", message.author.name, user_token)
|
||||||
|
with open('members.json', 'w') as json_file:
|
||||||
|
json.dump(users, json_file)
|
||||||
|
if rank == 1:
|
||||||
|
await member.add_roles(roles['top1'])
|
||||||
|
response = "Congratulations, you're now Top 1. But for how long ?"
|
||||||
|
|
||||||
|
elif (rank <= 10):
|
||||||
|
await member.add_roles(roles['top10'])
|
||||||
|
response = "You've been granted the Top 10 role. Now, go away and flag !"
|
||||||
|
|
||||||
|
elif rank <= 50:
|
||||||
|
await member.add_roles(roles['top50'])
|
||||||
|
response = "You've been granted the Top 50 role. Now, go away and flag !"
|
||||||
|
|
||||||
|
else:
|
||||||
|
response = "No role for you now, but I'll keep watching you."
|
||||||
|
except IndexError:
|
||||||
|
response = 'usage: !connect 42ctf_token'
|
||||||
|
await message.author.create_dm()
|
||||||
|
await message.author.dm_channel.send(response)
|
||||||
|
|
||||||
|
|
||||||
|
client.run(TOKEN)
|
|
@ -2,89 +2,67 @@
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12 col-md-9">
|
<div class="col-sm-12 col-md-9">
|
||||||
<div class="ctf-block">
|
<div class="ctf-block">
|
||||||
<div class="ctf-head">
|
<div class="ctf-head">
|
||||||
<h3>Edit info</h3>
|
<h3>Edit info</h3>
|
||||||
</div>
|
|
||||||
<div class="bloc-body">
|
|
||||||
<div class="col-sm-12 col-md-12 mx-auto">
|
|
||||||
{{ u_form.non_field_errors }}
|
|
||||||
{% if error is not None %}
|
|
||||||
<span class="message error-msg">{{ error }}</span>
|
|
||||||
{% elif success is not None %}
|
|
||||||
<span class="message success-msg">{{ success }}</span>
|
|
||||||
{% endif %}
|
|
||||||
<form method='POST'>
|
|
||||||
<div class="edit-infos-grp">
|
|
||||||
{%csrf_token%}
|
|
||||||
<label for="{{ u_form.username.id_for_label }}">{% trans "Username" %} *</label>
|
|
||||||
{{ u_form.username.errors}}
|
|
||||||
{{u_form.username}}
|
|
||||||
</br>
|
|
||||||
<label for="{{ u_form.email.id_for_label }}">{% trans "Email" %} *</label>
|
|
||||||
{{ u_form.email.errors}}
|
|
||||||
{{u_form.email}}
|
|
||||||
</br>
|
|
||||||
</br>
|
|
||||||
<label for="{{ p_form.portfolio_site.id_for_label }}">{% trans "Website" %}</label>
|
|
||||||
{{p_form.portfolio_site}}
|
|
||||||
</br>
|
|
||||||
</br>Token
|
|
||||||
<input type='text' readonly value='{{token}}'>
|
|
||||||
</br>
|
|
||||||
<input class="form-control" type="submit" value="{% trans " Apply" %}">
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="bloc-body">
|
||||||
<div class="ctf-block">
|
<div class="col-sm-12 col-md-12 mx-auto">
|
||||||
<div class="ctf-head">
|
{{ u_form.non_field_errors }}
|
||||||
<h3>{% trans "Connected accounts" %}</h3>
|
{% if error is not None %}
|
||||||
</div>
|
<span class="message error-msg">{{ error }}</span>
|
||||||
<div class="bloc-body">
|
{% elif success is not None %}
|
||||||
<div class="d-flex">
|
<span class="message success-msg">{{ success }}</span>
|
||||||
{% if user.userprofileinfo.discord_id|length > 0 %}
|
{% endif %}
|
||||||
<form action="{% url 'accounts:connections-disconnect-discord' %}" method='POST'
|
<form method='POST'>
|
||||||
class="form-inline p-2">
|
<div class="edit-infos-grp">
|
||||||
{%csrf_token%}
|
{%csrf_token%}
|
||||||
<button class="btn btn-dark" type="submit">{% trans "Disconnect Discord" %}</button>
|
<label for="{{ u_form.username.id_for_label }}">{% trans "Username" %} *</label>
|
||||||
</form>
|
{{ u_form.username.errors}}
|
||||||
{% else %}
|
{{u_form.username}}
|
||||||
<form action="{% url 'accounts:connections-connect-discord' %}" method='POST'
|
</br>
|
||||||
class="form-inline p-2">
|
<label for="{{ u_form.email.id_for_label }}">{% trans "Email" %} *</label>
|
||||||
{%csrf_token%}
|
{{ u_form.email.errors}}
|
||||||
<button class="btn btn-dark" type="submit">{% trans "Connect Discord" %}</button>
|
{{u_form.email}}
|
||||||
</form>
|
</br>
|
||||||
{% endif %}
|
</br>
|
||||||
</div>
|
<label for="{{ p_form.portfolio_site.id_for_label }}">{% trans "Website" %}</label>
|
||||||
|
{{p_form.portfolio_site}}
|
||||||
|
</br>
|
||||||
|
</br>Token
|
||||||
|
<input type='text' readonly value='{{token}}'>
|
||||||
|
</br>
|
||||||
|
<input class="form-control" type="submit" value="{% trans "Apply" %}">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="d-none d-md-block col-10 col-md-3 right-sidebar">
|
</div>
|
||||||
<ul class="list-group">
|
<div class="d-none d-md-block col-10 col-md-3 right-sidebar">
|
||||||
|
<ul class="list-group">
|
||||||
<li class="list-group-item">{{ user.username }}</li>
|
<li class="list-group-item">{{ user.username }}</li>
|
||||||
<li class="list-group-item">{% trans "Score" %} : {{ user.userprofileinfo.score }}</li>
|
<li class="list-group-item">{% trans "Score" %} : {{ user.userprofileinfo.score }}</li>
|
||||||
{% if user.userprofileinfo.portfolio_site %}
|
{% if user.userprofileinfo.portfolio_site %}
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
<a href="{{ user.userprofileinfo.portfolio_site }}" target="_blank">
|
<a href="{{ user.userprofileinfo.portfolio_site }}" target="_blank">
|
||||||
{{ user.userprofileinfo.portfolio_site }}
|
{{ user.userprofileinfo.portfolio_site }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li class="list-group-item">{% trans "Registered since" %} {{ user.date_joined|date:"Y-m-d" }}</li>
|
<li class="list-group-item">{% trans "Registered since" %} {{ user.date_joined|date:"Y-m-d" }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="list-group">
|
<ul class="list-group">
|
||||||
<form method='GET' action="{% url 'accounts:delete_account' %}">
|
<form method='GET' action="{% url 'accounts:delete_account' %}">
|
||||||
{%csrf_token%}
|
{%csrf_token%}
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
<input class="form-control" type="submit" value="{% trans " Delete my account" %}">
|
<input class="form-control" type="submit" value="{% trans "Delete my account" %}">
|
||||||
</li>
|
</li>
|
||||||
</form>
|
</form>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ from django.views.decorators.http import require_POST
|
||||||
from django.views.defaults import bad_request
|
from django.views.defaults import bad_request
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
from django.contrib.sites.models import Site
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
oauth = OAuth()
|
oauth = OAuth()
|
||||||
|
@ -24,9 +23,8 @@ oauth.register(
|
||||||
def connect(request):
|
def connect(request):
|
||||||
if request.user.userprofileinfo.discord_id:
|
if request.user.userprofileinfo.discord_id:
|
||||||
return bad_request(request, "Already connected")
|
return bad_request(request, "Already connected")
|
||||||
site = Site.objects.get_current()
|
|
||||||
redirect_uri = reverse('accounts:connections-connect-discord-authorize')
|
redirect_uri = reverse('accounts:connections-connect-discord-authorize')
|
||||||
redirect_uri = "https://" + site.domain + redirect_uri[3:] # remove language code
|
redirect_uri = request.build_absolute_uri(redirect_uri)
|
||||||
print(redirect_uri)
|
print(redirect_uri)
|
||||||
return oauth.discord.authorize_redirect(request, redirect_uri)
|
return oauth.discord.authorize_redirect(request, redirect_uri)
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,17 @@ def profile(request, user_name):
|
||||||
|
|
||||||
return render(request,'accounts/profile.html', {'user':user_obj, 'solves':solves,'solved':solved,'catsDatas': catsDatas, 'pointDatas': pointDatas,
|
return render(request,'accounts/profile.html', {'user':user_obj, 'solves':solves,'solved':solved,'catsDatas': catsDatas, 'pointDatas': pointDatas,
|
||||||
'rank': rank, 'score' : somme, 'member' : member, 'cats':cats})
|
'rank': rank, 'score' : somme, 'member' : member, 'cats':cats})
|
||||||
<<<<<<< HEAD
|
|
||||||
|
def rank(request, token):
|
||||||
|
all_users = UserProfileInfo.objects.filter(score__gt=0).select_related().order_by('-score', 'last_submission_date', 'user__username')
|
||||||
|
|
||||||
|
rank = 1
|
||||||
|
for elem in all_users:
|
||||||
|
if elem.token == token:
|
||||||
|
break
|
||||||
|
rank += 1
|
||||||
|
data = {"rank": rank}
|
||||||
|
return JsonResponse(data)
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def delete_account(request):
|
def delete_account(request):
|
||||||
|
@ -172,14 +182,3 @@ def delete_account(request):
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return render(request, 'accounts/delete.html', {'deleted': False, 'bad_password': False} )
|
return render(request, 'accounts/delete.html', {'deleted': False, 'bad_password': False} )
|
||||||
|
|
||||||
def rank(request, token):
|
|
||||||
all_users = UserProfileInfo.objects.filter(score__gt=0).select_related().order_by('-score', 'last_submission_date', 'user__username')
|
|
||||||
|
|
||||||
rank = 1
|
|
||||||
for elem in all_users:
|
|
||||||
if elem.token == token:
|
|
||||||
break
|
|
||||||
rank += 1
|
|
||||||
data = {"rank": rank}
|
|
||||||
return JsonResponse(data)
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
from django.contrib import admin
|
|
||||||
|
|
||||||
# Register your models here.
|
|
|
@ -1,6 +0,0 @@
|
||||||
from django.apps import AppConfig
|
|
||||||
|
|
||||||
|
|
||||||
class ApiConfig(AppConfig):
|
|
||||||
default_auto_field = 'django.db.models.BigAutoField'
|
|
||||||
name = 'api'
|
|
|
@ -1,3 +0,0 @@
|
||||||
from django.db import models
|
|
||||||
|
|
||||||
# Create your models here.
|
|
|
@ -1,3 +0,0 @@
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
# Create your tests here.
|
|
|
@ -1,6 +0,0 @@
|
||||||
from django.urls import path
|
|
||||||
from . import views
|
|
||||||
|
|
||||||
urlpatterns = [
|
|
||||||
path('bot/discord', views.discord_bot, name='discord_bot'),
|
|
||||||
]
|
|
|
@ -1,27 +0,0 @@
|
||||||
from django.shortcuts import render
|
|
||||||
from accounts.models import UserProfileInfo
|
|
||||||
from django.http import JsonResponse
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Create your views here.
|
|
||||||
|
|
||||||
|
|
||||||
def discord_bot(request):
|
|
||||||
if request.method != 'GET':
|
|
||||||
return JsonResponse({'error':'bad request'})
|
|
||||||
|
|
||||||
token = request.GET.get('token')
|
|
||||||
auth_token = os.getenv('BOT_TOKEN')
|
|
||||||
|
|
||||||
if (token != auth_token or not auth_token):
|
|
||||||
return JsonResponse({'error':'not authorized'})
|
|
||||||
|
|
||||||
all_users = UserProfileInfo.objects.select_related().order_by('-score', 'last_submission_date', 'user__username')
|
|
||||||
data = {}
|
|
||||||
rank = 1
|
|
||||||
for user in all_users:
|
|
||||||
if user.discord_id:
|
|
||||||
data[user.discord_id] = rank
|
|
||||||
rank += 1
|
|
||||||
|
|
||||||
return JsonResponse(data)
|
|
|
@ -38,7 +38,6 @@ INSTALLED_APPS = [
|
||||||
'scoreboard.apps.ScoreboardConfig',
|
'scoreboard.apps.ScoreboardConfig',
|
||||||
'resources.apps.ResourcesConfig',
|
'resources.apps.ResourcesConfig',
|
||||||
'django.contrib.sites',
|
'django.contrib.sites',
|
||||||
'api.apps.ApiConfig',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
|
|
@ -24,7 +24,6 @@ urlpatterns = [
|
||||||
path('', include('home.urls')),
|
path('', include('home.urls')),
|
||||||
path('set_lang/<str:lang_code>', home.views.set_language, name="set_language"),
|
path('set_lang/<str:lang_code>', home.views.set_language, name="set_language"),
|
||||||
path('dashboard/secret/admin', admin.site.urls),
|
path('dashboard/secret/admin', admin.site.urls),
|
||||||
path('api/', include('api.urls'))
|
|
||||||
]
|
]
|
||||||
|
|
||||||
urlpatterns += i18n_patterns(
|
urlpatterns += i18n_patterns(
|
||||||
|
|
Loading…
Reference in New Issue