Arreglado VotePoints, y Implementado el Cambio de Correo
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+10
-2
@@ -3,7 +3,7 @@ from django.contrib import admin
|
||||
from django import forms
|
||||
from .models import (
|
||||
Noticia, ClienteCategoria, SistemaOperativo, ServerSelection,
|
||||
RecruitAFriend, DownloadClientPage, ContentCreator, RecruitReward, GuildRenameSettings
|
||||
RecruitAFriend, DownloadClientPage, ContentCreator, RecruitReward, GuildRenameSettings, VoteSite
|
||||
)
|
||||
from django.db import connections
|
||||
import logging
|
||||
@@ -139,7 +139,15 @@ class GuildRenameSettingsAdmin(admin.ModelAdmin):
|
||||
(None, {
|
||||
'fields': ('cost',)
|
||||
}),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@admin.register(VoteSite)
|
||||
class VoteSiteAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'points', 'url', 'image_url')
|
||||
search_fields = ('name',)
|
||||
list_editable = ('points',)
|
||||
list_display_links = ('name',)
|
||||
|
||||
|
||||
# Registro de modelos en el admin
|
||||
|
||||
+40
-3
@@ -106,11 +106,13 @@ class ClaimedReward(models.Model):
|
||||
class AccountActivation(models.Model):
|
||||
username = models.CharField(max_length=17)
|
||||
email = models.EmailField()
|
||||
old_email = models.EmailField(null=True, blank=True)
|
||||
password = models.CharField(max_length=64) # Hash de la contraseña
|
||||
salt = models.BinaryField(max_length=32)
|
||||
verifier = models.BinaryField(max_length=32)
|
||||
recruiter_id = models.IntegerField(null=True, blank=True)
|
||||
hash = models.CharField(max_length=32, unique=True)
|
||||
old_email_hash = models.CharField(max_length=32, null=True, blank=True)
|
||||
created_at = models.DateTimeField(default=timezone.now)
|
||||
|
||||
def is_expired(self):
|
||||
@@ -118,14 +120,14 @@ class AccountActivation(models.Model):
|
||||
|
||||
|
||||
class SecurityToken(models.Model):
|
||||
user_id = models.IntegerField() # Referencia al ID del usuario en `acore_auth`
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
token = models.CharField(max_length=6)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
expires_at = models.DateTimeField()
|
||||
ip_address = models.GenericIPAddressField()
|
||||
|
||||
def __str__(self):
|
||||
return f"Token for user_id {self.user_id}"
|
||||
return f"Token for {self.user.username}"
|
||||
|
||||
|
||||
class GuildRenameSettings(models.Model):
|
||||
@@ -136,5 +138,40 @@ class GuildRenameSettings(models.Model):
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Configuración de Renombrar Hermandad"
|
||||
verbose_name_plural = "Configuraciones de Renombrar Hermandad"
|
||||
verbose_name_plural = "Configuraciones de Renombrar Hermandad"
|
||||
|
||||
|
||||
class VoteSite(models.Model):
|
||||
name = models.CharField(max_length=100, unique=True)
|
||||
url = models.URLField(max_length=200, help_text="URL del sitio de votación")
|
||||
image_url = models.URLField(max_length=300, help_text="URL completa de la imagen")
|
||||
points = models.IntegerField(default=1, help_text="Puntos otorgados por votar")
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class VoteLog(models.Model):
|
||||
account_id = models.IntegerField()
|
||||
vote_site = models.ForeignKey('VoteSite', on_delete=models.CASCADE)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
last_vote_time = models.DateTimeField(null=True, blank=True)
|
||||
processed = models.BooleanField(default=False)
|
||||
processed_at = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"Voto para {self.vote_site.name} por cuenta {self.account_id}"
|
||||
|
||||
|
||||
class HomeApiPoints(models.Model):
|
||||
accountID = models.IntegerField(unique=True)
|
||||
vp = models.IntegerField(default=0)
|
||||
dp = models.IntegerField(default=0)
|
||||
|
||||
class Meta:
|
||||
db_table = 'home_api_points'
|
||||
|
||||
def __str__(self):
|
||||
return f"Cuenta {self.accountID} - PV: {self.vp}, DP: {self.dp}"
|
||||
|
||||
@@ -1,70 +1,42 @@
|
||||
if (window.history.replaceState) {
|
||||
window.history.replaceState(null, null, window.location.href);
|
||||
};
|
||||
|
||||
$(function(){
|
||||
$(".toggle-password").click(function() {
|
||||
$(this).toggleClass("fa-eye fa-eye-slash");
|
||||
var type = $(this).hasClass("fa-eye-slash") ? "text" : "password";
|
||||
$("#password").attr("type", type);
|
||||
});
|
||||
});
|
||||
|
||||
$(function(){
|
||||
$(".toggle-token").click(function() {
|
||||
$(this).toggleClass("fa-eye fa-eye-slash");
|
||||
var type = $(this).hasClass("fa-eye-slash") ? "text" : "password";
|
||||
$("#security-token").attr("type", type);
|
||||
});
|
||||
});
|
||||
|
||||
$(function(){
|
||||
$('#conf-new-email').on("cut copy paste",function(e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
});
|
||||
|
||||
$(function(){
|
||||
$('.change-email-button').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
$(document).ready(function() {
|
||||
$('#nw-change-email-form').on('submit', function(e) {
|
||||
e.preventDefault(); // Evitar el envío por defecto del formulario
|
||||
$("#change-email-response").empty();
|
||||
|
||||
var button = $(this);
|
||||
var buttonoriginal = button.html();
|
||||
var bValue = button.data('id');
|
||||
var data = {changeemail: bValue};
|
||||
data = $("#uw-change-email-form").serialize() + '&' + $.param(data);
|
||||
var form = $(this);
|
||||
var button = $('.change-email-button');
|
||||
var originalText = button.html();
|
||||
|
||||
changeButton(button, 'Cambiando correo');
|
||||
button.html("Cambiando correo...");
|
||||
button.prop("disabled", true);
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '',
|
||||
data: data,
|
||||
url: form.attr('action'),
|
||||
data: form.serialize(), // Serializar los datos correctamente
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
$("#change-email-response").append(data.message).hide().slideDown();
|
||||
success: function(response) {
|
||||
$("#change-email-response").html(response.message).hide().slideDown();
|
||||
|
||||
if (data.success === true) {
|
||||
if (response.success) {
|
||||
button.html("Correo cambiado");
|
||||
button.css("color","#d79602");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
setTimeout(function() {
|
||||
$("#change-email-response").slideUp( function() {
|
||||
$("#change-email-response").empty();
|
||||
restoreButton(button, buttonoriginal);
|
||||
$("#change-email-response").slideUp(function() {
|
||||
$("#change-email-response").empty();
|
||||
button.html(originalText);
|
||||
button.prop("disabled", false);
|
||||
});
|
||||
}, 5000);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
setTimeout(function() {
|
||||
alert("Algo ha salido mal. Por favor intente más tarde");
|
||||
window.location.reload();
|
||||
}, 2000);
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Error:", error);
|
||||
console.error("Detalles:", xhr.responseText);
|
||||
$("#change-email-response").html('<span class="red-form-response">Algo ha salido mal. Inténtelo de nuevo.</span>');
|
||||
button.html(originalText);
|
||||
button.prop("disabled", false);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
$(document).ready(function() {
|
||||
$('.vote-button').each(function() {
|
||||
var button = $(this);
|
||||
var remainingTime = button.data('remaining-time');
|
||||
|
||||
if (remainingTime) {
|
||||
startCooldownTimer(button, remainingTime);
|
||||
}
|
||||
});
|
||||
|
||||
$('.vote-button').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
$("#voteResponse").empty();
|
||||
|
||||
var button = $(this);
|
||||
var voteUrl = button.data('url').trim();
|
||||
var data = { vote: voteUrl };
|
||||
|
||||
button.html("Votando...");
|
||||
button.prop("disabled", true);
|
||||
|
||||
var otherWindow = window.open(voteUrl, "_blank");
|
||||
otherWindow.opener = null;
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '',
|
||||
data: data,
|
||||
dataType: 'json',
|
||||
success: function(response) {
|
||||
$("#voteResponse").html(response.message).hide().slideDown();
|
||||
|
||||
if (response.success) {
|
||||
button.html("Votado");
|
||||
button.prop("disabled", true);
|
||||
} else {
|
||||
button.html("Votar");
|
||||
button.prop("disabled", false);
|
||||
}
|
||||
|
||||
// Ocultar el mensaje después de 5 segundos
|
||||
setTimeout(function() {
|
||||
$("#voteResponse").slideUp(function() {
|
||||
$("#voteResponse").empty();
|
||||
});
|
||||
}, 5000);
|
||||
},
|
||||
error: function() {
|
||||
$("#voteResponse").html('<span class="red-form-response">Algo ha salido mal. Por favor, inténtalo más tarde.</span>');
|
||||
|
||||
// Ocultar el mensaje después de 5 segundos en caso de error
|
||||
setTimeout(function() {
|
||||
$("#voteResponse").slideUp(function() {
|
||||
$("#voteResponse").empty();
|
||||
});
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function startCooldownTimer(button, remainingTime) {
|
||||
var interval = setInterval(function() {
|
||||
if (remainingTime <= 0) {
|
||||
clearInterval(interval);
|
||||
button.html("Votar");
|
||||
button.prop("disabled", false);
|
||||
} else {
|
||||
var hours = Math.floor(remainingTime / 3600);
|
||||
var minutes = Math.floor((remainingTime % 3600) / 60);
|
||||
button.html(`Espera ${hours}h ${minutes}m`);
|
||||
remainingTime--;
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Activación del Nuevo Correo</title>
|
||||
</head>
|
||||
<body>
|
||||
<table style="width: 100%; max-width: 600px; margin: 0 auto; border: 1px solid #dddddd; padding: 20px;">
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<h2>Activación de Nuevo Correo</h2>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>Hola {{ username }},</p>
|
||||
<p>Tu solicitud para cambiar el correo electrónico en <strong>{{ NOMBRE_SERVIDOR }}</strong> ha sido recibida.</p>
|
||||
<p>Por favor, haz clic en el siguiente enlace para confirmar tu nuevo correo:</p>
|
||||
<p style="text-align: center;">
|
||||
<a href="{{ activation_link }}" style="display: inline-block; padding: 10px 20px; background-color: #28a745; color: white; text-decoration: none; border-radius: 5px;">Activar nuevo correo</a>
|
||||
</p>
|
||||
<p>Si no realizaste esta solicitud, por favor contacta con soporte.</p>
|
||||
<p>Atentamente,<br>El equipo de {{ NOMBRE_SERVIDOR }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Confirmación de Cambio de Correo</title>
|
||||
</head>
|
||||
<body>
|
||||
<table style="width: 100%; max-width: 600px; margin: 0 auto; border: 1px solid #dddddd; padding: 20px;">
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<h2>Confirmación de Cambio de Correo</h2>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>Hola {{ username }},</p>
|
||||
<p>Has solicitado cambiar tu correo electrónico registrado en <strong>{{ NOMBRE_SERVIDOR }}</strong>.</p>
|
||||
<p>Para confirmar este cambio, haz clic en el siguiente enlace:</p>
|
||||
<p style="text-align: center;">
|
||||
<a href="{{ confirm_link }}" style="display: inline-block; padding: 10px 20px; background-color: #007bff; color: white; text-decoration: none; border-radius: 5px;">Confirmar cambio</a>
|
||||
</p>
|
||||
<p>Si no solicitaste este cambio, por favor ignora este correo.</p>
|
||||
<p>Atentamente,<br>El equipo de {{ NOMBRE_SERVIDOR }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Notificación de Cambio de Correo</title>
|
||||
</head>
|
||||
<body>
|
||||
<table style="width: 100%; max-width: 600px; margin: 0 auto; border: 1px solid #dddddd; padding: 20px;">
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<h2>Cambio de Correo Exitoso</h2>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>Hola {{ username }},</p>
|
||||
<p>Te notificamos que tu correo electrónico en <strong>{{ NOMBRE_SERVIDOR }}</strong> ha sido cambiado exitosamente al siguiente correo:</p>
|
||||
<p style="text-align: center;">
|
||||
<strong>{{ new_email }}</strong>
|
||||
</p>
|
||||
<p>Si no realizaste este cambio, por favor contacta inmediatamente con soporte.</p>
|
||||
<p>Atentamente,<br>El equipo de {{ NOMBRE_SERVIDOR }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -14,10 +14,42 @@
|
||||
<div class="centered">
|
||||
<br>
|
||||
<br>
|
||||
<span class="red-form-response">El cambio de correo ya no es una herramienta disponible por autogestión.</span>
|
||||
<hr>
|
||||
<div class="alert-message" id="change-email-response"></div>
|
||||
<br>
|
||||
<form id="nw-change-email-form" method="POST" accept-charset="utf-8">
|
||||
{% csrf_token %}
|
||||
<table class="middle-center-table">
|
||||
<tr>
|
||||
<td><input type="password" maxlength="16" name="cur-password" id="cur-password" placeholder="Contraseña actual" required></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="email" name="cur-email" id="cur-email" placeholder="Correo actual" required></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="email" name="new-email" id="new-email" placeholder="Nuevo correo" required></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="email" name="conf-new-email" id="conf-new-email" placeholder="Confirmar nuevo correo" required></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="text" maxlength="6" name="security-token" id="security-token" placeholder="Token de seguridad" required>
|
||||
<span class="far fa-eye toggle-token"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<button type="submit" class="change-email-button">Cambiar Correo</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<div class="alert-message" id="change-email-response"></div>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
|
||||
</hr>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
<script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js-handlers/security_token_response.js"></script>
|
||||
<script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js-handlers/change_password_response.js"></script>
|
||||
<script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js-handlers/rename_guild_response.js"></script>
|
||||
<script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js-handlers/vote_points_response.js"></script>
|
||||
<script>var aowow_tooltips = { "colorlinks": true, "iconizelinks": true, "renamelinks": true }</script>
|
||||
<script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js/nw-scripts.js"></script>
|
||||
|
||||
|
||||
@@ -20,9 +20,17 @@
|
||||
<legend>Estado de la cuenta</legend>
|
||||
<div class="separate">
|
||||
<img src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-images/nw-ranks/1_Newbie.svg" class="nw-rank" alt="Nivel 1" title="Nivel 1">
|
||||
<p>PD: <span>0</span></p>
|
||||
<p>PV: <span>0</span></p>
|
||||
<p>Token de Seguridad: <span>Sin solicitar</span></p>
|
||||
<p>PD: <span>{{ dp }}</span></p>
|
||||
<p>PV: <span>{{ vp }}</span></p>
|
||||
<p>Token de Seguridad:
|
||||
<span>
|
||||
{% if token_status == "Solicitado" %}
|
||||
{{ token_status }} - {{ token_date }}
|
||||
{% else %}
|
||||
{{ token_status }}
|
||||
{% endif %}
|
||||
</span>
|
||||
</p>
|
||||
|
||||
{% if account_status.is_banned %}
|
||||
<p>Cuenta baneada: <span>Sí</span></p>
|
||||
|
||||
@@ -52,122 +52,32 @@
|
||||
<button class="refresh-button" onclick="doRefresh();"><img class="refresh-icon" src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-images/nw-icons/refresh.webp" title="Refrescar" alt="Refrescar"></button>
|
||||
<p><span>Nota:</span> Gtop100 puede demorar unos minutos en acreditar el voto.</p>
|
||||
<br>
|
||||
<div class="inline-div">
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td><img class="img-med-icon" src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-images/nw-vote-sites/gtop100.jpg" title="Gtop100" alt="Gtop100"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gtop100</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="lefted">PV: <span>1</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="lefted"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<form action="" method="POST" id="uw-vote-form" accept-charset="utf-8">
|
||||
<button type="submit" name="vote" class="vote-button" value="https://gtop100.com/topsites/World-of-Warcraft/sitedetails/{{ NOMBRE_SERVIDOR }}-94649?vote=1&pingUsername=91402">Votar</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr><tr>
|
||||
</tr></tbody></table>
|
||||
</div>
|
||||
<div class="inline-div">
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td><img class="img-med-icon" src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-images/nw-vote-sites/topg.webp" title="TopG" alt="TopG"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TopG</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="lefted">PV: <span>1</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="lefted"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<form action="" method="POST" id="uw-vote-form" accept-charset="utf-8">
|
||||
<button type="submit" name="vote" class="vote-button" value="https://topg.org/wow-private-servers/in-496618-91402">Votar</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr><tr>
|
||||
</tr></tbody></table>
|
||||
</div>
|
||||
<div class="inline-div">
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td><img class="img-med-icon" src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-images/nw-vote-sites/top100arena.jpg" title="Top100arena" alt="Top100arena"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Top100arena</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="lefted">PV: <span>1</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="lefted"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<form action="" method="POST" id="uw-vote-form" accept-charset="utf-8">
|
||||
<button type="submit" name="vote" class="vote-button" value="http://www.top100arena.com/in.asp?id=94147&incentive=91402">Votar</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr><tr>
|
||||
</tr></tbody></table>
|
||||
</div>
|
||||
<div class="inline-div">
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td><img class="img-med-icon" src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-images/nw-vote-sites/arenatop100.webp" title="Arena-Top100" alt="Arena-Top100"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Arena-Top100</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="lefted">PV: <span>1</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="lefted"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<form action="" method="POST" id="uw-vote-form" accept-charset="utf-8">
|
||||
<button type="submit" name="vote" class="vote-button" value="https://www.arena-top100.com/index.php?a=in&u={{ NOMBRE_SERVIDOR }}&id=91402">Votar</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr><tr>
|
||||
</tr></tbody></table>
|
||||
</div>
|
||||
<div id="vote-panel">
|
||||
<div id="vote-panel">
|
||||
{% for site in vote_sites %}
|
||||
<div class="inline-div">
|
||||
<table>
|
||||
<tr>
|
||||
<td><img class="img-med-icon" src="{{ site.image_url }}" title="{{ site.name }}" alt="{{ site.name }}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ site.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PV: <span>{{ site.points }}</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<form method="POST" class="nw-vote-form" accept-charset="utf-8">
|
||||
{% csrf_token %}
|
||||
<button type="button" class="vote-button" data-url="{{ site.url }}" data-remaining-time="{{ site.remaining_time }}">Votar</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<hr>
|
||||
<div class="alert-message" id="voteResponse"></div>
|
||||
<br>
|
||||
|
||||
+3
-1
@@ -23,7 +23,9 @@ urlpatterns = [
|
||||
path('not-found/', views.not_found, name='not-found'),
|
||||
path('change-password/', views.change_password_view, name='change_password'),
|
||||
path('security-token/', views.security_token_view, name='security_token'),
|
||||
path('change-email/', views.change_email_view, name='change_email'),
|
||||
path('change-email/', views.change_email_view, name='change-email'),
|
||||
path('confirm-old-email/', views.confirm_old_email_view, name='confirm-old-email'),
|
||||
path('confirm-new-email/', views.confirm_new_email_view, name='confirm-new-email'),
|
||||
path('promo-code/', views.promo_code_view, name='promo_code'),
|
||||
path('transfer-d-points/', views.transfer_d_points_view, name='transfer_d_points'),
|
||||
path('rename-guild/', views.rename_guild_view, name='rename-guild'),
|
||||
|
||||
+214
-19
@@ -5,12 +5,12 @@ import binascii
|
||||
import os
|
||||
import re
|
||||
from django.shortcuts import render, redirect
|
||||
from django.http import JsonResponse
|
||||
from django.http import HttpResponse, JsonResponse
|
||||
from django.db import connections
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth import logout
|
||||
from django import forms
|
||||
from .models import Noticia, ClienteCategoria, ServerSelection, RecruitAFriend, DownloadClientPage, ContentCreator, RecruitReward, ClaimedReward, AccountActivation, SecurityToken, GuildRenameSettings
|
||||
from .models import Noticia, ClienteCategoria, ServerSelection, RecruitAFriend, DownloadClientPage, ContentCreator, RecruitReward, ClaimedReward, AccountActivation, SecurityToken, GuildRenameSettings, VoteSite, VoteLog, HomeApiPoints
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
@@ -22,7 +22,6 @@ from django.utils.crypto import get_random_string
|
||||
from django.conf import settings
|
||||
import secrets
|
||||
|
||||
|
||||
# Configuración del logger
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -340,7 +339,7 @@ def register_view(request):
|
||||
)
|
||||
|
||||
# Enviar correo de activación
|
||||
activation_link = f"http://localhost:8009/es/activate-account?act={activation_hash}"
|
||||
activation_link = f"{settings.URL_PRINCIPAL}/es/activate-account?act={activation_hash}"
|
||||
context = {
|
||||
'username': username,
|
||||
'password': password,
|
||||
@@ -610,6 +609,21 @@ def my_account(request):
|
||||
|
||||
# Obtener el estado de la cuenta
|
||||
account_status = get_account_status(account_id)
|
||||
|
||||
# Obtener los puntos (DP y VP) del usuario desde la tabla `home_api_points`
|
||||
user_points = HomeApiPoints.objects.filter(accountID=account_id).first()
|
||||
dp = user_points.dp if user_points else 0
|
||||
vp = user_points.vp if user_points else 0
|
||||
|
||||
|
||||
# Obtener el estado del token de seguridad
|
||||
security_token = SecurityToken.objects.filter(user_id=account_id).first()
|
||||
if security_token:
|
||||
token_status = "Solicitado"
|
||||
token_date = security_token.created_at.strftime('%H:%M:%S %d-%m-%Y')
|
||||
else:
|
||||
token_status = "Sin solicitar"
|
||||
token_date = None
|
||||
|
||||
return render(request, 'my-account/my-account.html', {
|
||||
'is_logged_in': is_logged_in,
|
||||
@@ -620,10 +634,15 @@ def my_account(request):
|
||||
'last_ip': account_data[4],
|
||||
'last_attempt_ip': account_data[5],
|
||||
'joindate': formatear_fecha(account_data[6]),
|
||||
|
||||
},
|
||||
'account_status': account_status,
|
||||
'characters': characters,
|
||||
'has_characters': has_characters,
|
||||
'dp': dp,
|
||||
'vp': vp,
|
||||
'token_status': token_status,
|
||||
'token_date': token_date
|
||||
})
|
||||
|
||||
|
||||
@@ -951,15 +970,146 @@ def send_security_token_email(email, username, token, ip_address):
|
||||
context=context
|
||||
)
|
||||
|
||||
|
||||
|
||||
def change_email_view(request):
|
||||
"""
|
||||
Vista para la página de 'Cambiar Correo'.
|
||||
Simplemente renderiza un template con información relevante.
|
||||
"""
|
||||
username = request.session.get('username')
|
||||
if not username:
|
||||
return redirect('login')
|
||||
|
||||
# Obtener el usuario desde la base de datos de `acore_auth`
|
||||
with connections['acore_auth'].cursor() as cursor:
|
||||
cursor.execute("""
|
||||
SELECT id, email, reg_mail
|
||||
FROM account
|
||||
WHERE username = %s
|
||||
""", [username])
|
||||
account_data = cursor.fetchone()
|
||||
|
||||
if not account_data:
|
||||
return redirect('login')
|
||||
|
||||
user_id, current_email, reg_email = account_data
|
||||
security_token = SecurityToken.objects.filter(user_id=user_id).first()
|
||||
|
||||
if request.method == 'POST':
|
||||
print("Datos recibidos:", request.POST)
|
||||
|
||||
current_password = request.POST.get('cur-password', '').strip()
|
||||
current_email_input = request.POST.get('cur-email', '').strip()
|
||||
new_email = request.POST.get('new-email', '').strip()
|
||||
conf_new_email = request.POST.get('conf-new-email', '').strip()
|
||||
token = request.POST.get('security-token', '').strip()
|
||||
|
||||
# Validar los campos
|
||||
if not all([current_password, current_email_input, new_email, conf_new_email, token]):
|
||||
return JsonResponse({'success': False, 'message': 'Por favor, complete todos los campos.'})
|
||||
|
||||
if current_email_input != current_email:
|
||||
return JsonResponse({'success': False, 'message': 'El correo actual no es correcto.'})
|
||||
|
||||
if new_email != conf_new_email:
|
||||
return JsonResponse({'success': False, 'message': 'Los correos no coinciden.'})
|
||||
|
||||
if not re.match(r'^[a-zA-Z0-9._%+-]+@gmail\.com$', new_email):
|
||||
return JsonResponse({'success': False, 'message': 'El nuevo correo no es válido.'})
|
||||
|
||||
if not security_token or security_token.token != token:
|
||||
return JsonResponse({'success': False, 'message': 'Token de seguridad incorrecto.'})
|
||||
|
||||
if not authenticate(username, current_password):
|
||||
return JsonResponse({'success': False, 'message': 'Contraseña incorrecta.'})
|
||||
|
||||
# Generar hashes
|
||||
old_email_hash = secrets.token_urlsafe(16)
|
||||
new_email_hash = secrets.token_urlsafe(16)
|
||||
|
||||
# Guardar en `AccountActivation`
|
||||
AccountActivation.objects.create(
|
||||
username=username,
|
||||
email=new_email,
|
||||
old_email=current_email,
|
||||
password='',
|
||||
salt=b'',
|
||||
verifier=b'',
|
||||
recruiter_id=user_id,
|
||||
hash=new_email_hash,
|
||||
old_email_hash=old_email_hash
|
||||
)
|
||||
|
||||
# Enviar confirmación al correo actual
|
||||
confirm_old_email_link = f"{settings.URL_PRINCIPAL}/es/confirm-old-email?hash={old_email_hash}"
|
||||
context_old_email = {
|
||||
'username': username,
|
||||
'confirm_link': confirm_old_email_link,
|
||||
'NOMBRE_SERVIDOR': settings.NOMBRE_SERVIDOR
|
||||
}
|
||||
enviar_correo(
|
||||
subject=f'Confirme el cambio de correo para {username}',
|
||||
to_email=current_email,
|
||||
template='emails/confirm_old_email.html',
|
||||
context=context_old_email
|
||||
)
|
||||
|
||||
return JsonResponse({'success': True, 'message': 'Se ha enviado un correo de confirmación al correo actual.'})
|
||||
|
||||
return render(request, 'account/change_email.html')
|
||||
|
||||
|
||||
|
||||
def confirm_old_email_view(request):
|
||||
hash = request.GET.get('hash')
|
||||
activation = AccountActivation.objects.filter(old_email_hash=hash).first()
|
||||
|
||||
if not activation:
|
||||
return HttpResponse('Enlace no válido o expirado.', status=400)
|
||||
|
||||
# Enviar correo al nuevo correo para confirmar el cambio
|
||||
activation_link = f"{settings.URL_PRINCIPAL}/es/confirm-new-email?hash={activation.hash}"
|
||||
context_new_email = {
|
||||
'username': activation.username,
|
||||
'activation_link': activation_link,
|
||||
'NOMBRE_SERVIDOR': settings.NOMBRE_SERVIDOR
|
||||
}
|
||||
enviar_correo(
|
||||
subject=f'Confirme su nuevo correo para {activation.username}',
|
||||
to_email=activation.email,
|
||||
template='emails/confirm_new_email.html',
|
||||
context=context_new_email
|
||||
)
|
||||
|
||||
return HttpResponse('Correo confirmado. Se ha enviado un enlace al nuevo correo.')
|
||||
|
||||
|
||||
def confirm_new_email_view(request):
|
||||
hash = request.GET.get('hash')
|
||||
activation = AccountActivation.objects.filter(hash=hash).first()
|
||||
|
||||
if not activation:
|
||||
return HttpResponse('Enlace no válido o expirado.', status=400)
|
||||
|
||||
# Actualizar el correo en la base de datos
|
||||
with connections['acore_auth'].cursor() as cursor:
|
||||
cursor.execute("""
|
||||
UPDATE account
|
||||
SET email = %s, reg_mail = %s
|
||||
WHERE username = %s
|
||||
""", [activation.email, activation.email, activation.username])
|
||||
|
||||
# Enviar notificación al correo anterior
|
||||
context_old_email = {
|
||||
'username': activation.username,
|
||||
'new_email': activation.email,
|
||||
'NOMBRE_SERVIDOR': settings.NOMBRE_SERVIDOR
|
||||
}
|
||||
enviar_correo(
|
||||
subject=f'Su correo ha sido cambiado en {settings.NOMBRE_SERVIDOR}',
|
||||
to_email=activation.old_email,
|
||||
template='emails/old_email_notification.html',
|
||||
context=context_old_email
|
||||
)
|
||||
|
||||
return HttpResponse('El cambio de correo ha sido confirmado y completado con éxito.')
|
||||
|
||||
|
||||
|
||||
def promo_code_view(request):
|
||||
return render(request, 'account/promo_code.html')
|
||||
|
||||
@@ -967,9 +1117,6 @@ def transfer_d_points_view(request):
|
||||
# Renderizar la plantilla para la transferencia de puntos
|
||||
return render(request, 'account/transfer_d_points.html')
|
||||
|
||||
|
||||
from .models import GuildRenameSettings
|
||||
|
||||
def rename_guild_view(request):
|
||||
# Verificar si el usuario está autenticado mediante la sesión
|
||||
username = request.session.get('username')
|
||||
@@ -1037,12 +1184,60 @@ def rename_guild_view(request):
|
||||
'rename_cost': rename_cost
|
||||
})
|
||||
|
||||
|
||||
def vote_points_view(request):
|
||||
"""
|
||||
Vista para la página de puntos de votación.
|
||||
"""
|
||||
return render(request, 'account/vote_points.html')
|
||||
# Verificar si el usuario tiene un `username` en la sesión
|
||||
username = request.session.get('username')
|
||||
if not username:
|
||||
return redirect('login')
|
||||
|
||||
# Obtener el `account_id` basado en el `username`
|
||||
with connections['acore_auth'].cursor() as cursor:
|
||||
cursor.execute("SELECT id FROM account WHERE username = %s", [username])
|
||||
account_data = cursor.fetchone()
|
||||
|
||||
if not account_data:
|
||||
return JsonResponse({'success': False, 'message': 'Cuenta no encontrada.'})
|
||||
|
||||
account_id = account_data[0]
|
||||
|
||||
if request.method == 'POST':
|
||||
vote_url = request.POST.get('vote').strip()
|
||||
|
||||
site = VoteSite.objects.filter(url=vote_url).first()
|
||||
if not site:
|
||||
return JsonResponse({'success': False, 'message': 'Sitio de votación no encontrado.'})
|
||||
|
||||
# Verificar si ya ha votado en las últimas 12 horas y 30 minutos
|
||||
last_vote = VoteLog.objects.filter(account_id=account_id, vote_site=site).order_by('-created_at').first()
|
||||
now = timezone.now()
|
||||
if last_vote:
|
||||
time_diff = now - last_vote.created_at
|
||||
cooldown_period = timedelta(hours=12, minutes=30)
|
||||
|
||||
if time_diff < cooldown_period:
|
||||
remaining_time = cooldown_period - time_diff
|
||||
hours, remainder = divmod(remaining_time.seconds, 3600)
|
||||
minutes, _ = divmod(remainder, 60)
|
||||
return JsonResponse({
|
||||
'success': False,
|
||||
'message': f'<span class="red-form-response">Tienes que esperar {hours} horas y {minutes} minutos antes de volver a votar.</span>'
|
||||
})
|
||||
|
||||
# Acreditar puntos al usuario y registrar el voto
|
||||
user_points = HomeApiPoints.objects.filter(accountID=account_id).first()
|
||||
if user_points:
|
||||
user_points.vp += site.points
|
||||
user_points.save()
|
||||
else:
|
||||
HomeApiPoints.objects.create(accountID=account_id, vp=site.points, dp=0)
|
||||
|
||||
# Registrar el voto
|
||||
VoteLog.objects.create(account_id=account_id, vote_site=site, last_vote_time=now)
|
||||
|
||||
return JsonResponse({'success': True, 'message': f'Has votado en {site.name}. Se han acreditado {site.points} PV.'})
|
||||
|
||||
vote_sites = VoteSite.objects.all()
|
||||
return render(request, 'account/vote_points.html', {'vote_sites': vote_sites})
|
||||
|
||||
def d_points_view(request):
|
||||
"""
|
||||
|
||||
Binary file not shown.
+1
-1
@@ -43,7 +43,7 @@ INSTALLED_APPS = [
|
||||
|
||||
# Configuración para AC SOAP
|
||||
AC_SOAP_URL = "http://127.0.0.1:2079"
|
||||
AC_SOAP_USER = "AC_SOAP"
|
||||
AC_SOAP_USER = " "
|
||||
AC_SOAP_PASSWORD = "Ladyamy89"
|
||||
AC_SOAP_URN = "urn:AC"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user