diff --git a/home/__pycache__/admin.cpython-313.pyc b/home/__pycache__/admin.cpython-313.pyc index 6145892..5df01a2 100644 Binary files a/home/__pycache__/admin.cpython-313.pyc and b/home/__pycache__/admin.cpython-313.pyc differ diff --git a/home/__pycache__/models.cpython-313.pyc b/home/__pycache__/models.cpython-313.pyc index 48b97e4..eaebdf1 100644 Binary files a/home/__pycache__/models.cpython-313.pyc and b/home/__pycache__/models.cpython-313.pyc differ diff --git a/home/__pycache__/tasks.cpython-313.pyc b/home/__pycache__/tasks.cpython-313.pyc new file mode 100644 index 0000000..7732d18 Binary files /dev/null and b/home/__pycache__/tasks.cpython-313.pyc differ diff --git a/home/__pycache__/urls.cpython-313.pyc b/home/__pycache__/urls.cpython-313.pyc index 0e12934..bd4ad0c 100644 Binary files a/home/__pycache__/urls.cpython-313.pyc and b/home/__pycache__/urls.cpython-313.pyc differ diff --git a/home/__pycache__/views.cpython-313.pyc b/home/__pycache__/views.cpython-313.pyc index 8b17fbb..ee78eb0 100644 Binary files a/home/__pycache__/views.cpython-313.pyc and b/home/__pycache__/views.cpython-313.pyc differ diff --git a/home/admin.py b/home/admin.py index 903fb61..78d2fc8 100644 --- a/home/admin.py +++ b/home/admin.py @@ -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 diff --git a/home/models.py b/home/models.py index 1800ab3..c636101 100644 --- a/home/models.py +++ b/home/models.py @@ -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}" \ No newline at end of file diff --git a/home/static/nw-themes/nw-ryu/nw-js-handlers/change_email_response.js b/home/static/nw-themes/nw-ryu/nw-js-handlers/change_email_response.js index 28ddd43..cc0b6bb 100644 --- a/home/static/nw-themes/nw-ryu/nw-js-handlers/change_email_response.js +++ b/home/static/nw-themes/nw-ryu/nw-js-handlers/change_email_response.js @@ -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('Algo ha salido mal. Inténtelo de nuevo.'); + button.html(originalText); + button.prop("disabled", false); } }); }); -}); \ No newline at end of file +}); diff --git a/home/static/nw-themes/nw-ryu/nw-js-handlers/vote_points_response.js b/home/static/nw-themes/nw-ryu/nw-js-handlers/vote_points_response.js new file mode 100644 index 0000000..2f54003 --- /dev/null +++ b/home/static/nw-themes/nw-ryu/nw-js-handlers/vote_points_response.js @@ -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('Algo ha salido mal. Por favor, inténtalo más tarde.'); + + // 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); +} diff --git a/home/templates/emails/confirm_new_email.html b/home/templates/emails/confirm_new_email.html new file mode 100644 index 0000000..ed97fd0 --- /dev/null +++ b/home/templates/emails/confirm_new_email.html @@ -0,0 +1,28 @@ + + + + + Activación del Nuevo Correo + + + + + + + + + +
+

Activación de Nuevo Correo

+
+

Hola {{ username }},

+

Tu solicitud para cambiar el correo electrónico en {{ NOMBRE_SERVIDOR }} ha sido recibida.

+

Por favor, haz clic en el siguiente enlace para confirmar tu nuevo correo:

+

+ Activar nuevo correo +

+

Si no realizaste esta solicitud, por favor contacta con soporte.

+

Atentamente,
El equipo de {{ NOMBRE_SERVIDOR }}

+
+ + diff --git a/home/templates/emails/confirm_old_email.html b/home/templates/emails/confirm_old_email.html new file mode 100644 index 0000000..1c7c0f4 --- /dev/null +++ b/home/templates/emails/confirm_old_email.html @@ -0,0 +1,28 @@ + + + + + Confirmación de Cambio de Correo + + + + + + + + + +
+

Confirmación de Cambio de Correo

+
+

Hola {{ username }},

+

Has solicitado cambiar tu correo electrónico registrado en {{ NOMBRE_SERVIDOR }}.

+

Para confirmar este cambio, haz clic en el siguiente enlace:

+

+ Confirmar cambio +

+

Si no solicitaste este cambio, por favor ignora este correo.

+

Atentamente,
El equipo de {{ NOMBRE_SERVIDOR }}

+
+ + diff --git a/home/templates/emails/old_email_notification.html b/home/templates/emails/old_email_notification.html new file mode 100644 index 0000000..6afbed1 --- /dev/null +++ b/home/templates/emails/old_email_notification.html @@ -0,0 +1,27 @@ + + + + + Notificación de Cambio de Correo + + + + + + + + + +
+

Cambio de Correo Exitoso

+
+

Hola {{ username }},

+

Te notificamos que tu correo electrónico en {{ NOMBRE_SERVIDOR }} ha sido cambiado exitosamente al siguiente correo:

+

+ {{ new_email }} +

+

Si no realizaste este cambio, por favor contacta inmediatamente con soporte.

+

Atentamente,
El equipo de {{ NOMBRE_SERVIDOR }}

+
+ + diff --git a/home/templates/partials/change_email.html b/home/templates/partials/change_email.html index a53d81f..175351f 100644 --- a/home/templates/partials/change_email.html +++ b/home/templates/partials/change_email.html @@ -14,10 +14,42 @@


- El cambio de correo ya no es una herramienta disponible por autogestión. -
-
-
+
+ {% csrf_token %} + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
+ + + + + +
diff --git a/home/templates/partials/head.html b/home/templates/partials/head.html index 05f7f72..4fdc02b 100644 --- a/home/templates/partials/head.html +++ b/home/templates/partials/head.html @@ -51,6 +51,7 @@ + diff --git a/home/templates/partials/my-account.html b/home/templates/partials/my-account.html index fd826c7..65d2334 100644 --- a/home/templates/partials/my-account.html +++ b/home/templates/partials/my-account.html @@ -20,9 +20,17 @@ Estado de la cuenta
Nivel 1 -

PD: 0

-

PV: 0

-

Token de Seguridad: Sin solicitar

+

PD: {{ dp }}

+

PV: {{ vp }}

+

Token de Seguridad: + + {% if token_status == "Solicitado" %} + {{ token_status }} - {{ token_date }} + {% else %} + {{ token_status }} + {% endif %} + +

{% if account_status.is_banned %}

Cuenta baneada:

diff --git a/home/templates/partials/vote_points.html b/home/templates/partials/vote_points.html index c69b3f3..db203e0 100644 --- a/home/templates/partials/vote_points.html +++ b/home/templates/partials/vote_points.html @@ -52,122 +52,32 @@

Nota: Gtop100 puede demorar unos minutos en acreditar el voto.


-
- - - - - - - - - - - - - - - - - - - - - - -
Gtop100
Gtop100

PV: 1

-
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - -
TopG
TopG

PV: 1

-
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - -
Top100arena
Top100arena

PV: 1

-
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - -
Arena-Top100
Arena-Top100

PV: 1

-
- -
-
-
+
+
+ {% for site in vote_sites %} +
+ + + + + + + + + + + + + +
{{ site.name }}
{{ site.name }}
PV: {{ site.points }}
+
+ {% csrf_token %} + +
+
+
+{% endfor %} +

diff --git a/home/urls.py b/home/urls.py index c8988be..6be487d 100644 --- a/home/urls.py +++ b/home/urls.py @@ -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'), diff --git a/home/views.py b/home/views.py index 263ec29..b4f7d90 100644 --- a/home/views.py +++ b/home/views.py @@ -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'Tienes que esperar {hours} horas y {minutes} minutos antes de volver a votar.' + }) + + # 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): """ diff --git a/novawow/__pycache__/settings.cpython-313.pyc b/novawow/__pycache__/settings.cpython-313.pyc index 8246ab7..3fcba23 100644 Binary files a/novawow/__pycache__/settings.cpython-313.pyc and b/novawow/__pycache__/settings.cpython-313.pyc differ diff --git a/novawow/settings.py b/novawow/settings.py index 6e4cc59..1764d33 100644 --- a/novawow/settings.py +++ b/novawow/settings.py @@ -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"