Complete processing pipeline for Signal

This commit is contained in:
2025-02-07 20:59:39 +00:00
parent dec9d28803
commit 9b3f28c631
42 changed files with 2879 additions and 0 deletions

0
core/views/__init__.py Normal file
View File

43
core/views/ais.py Normal file
View File

@@ -0,0 +1,43 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from mixins.views import (
ObjectCreate,
ObjectDelete,
ObjectList,
ObjectUpdate,
)
from core.forms import AIForm
from core.models import AI
from core.util import logs
log = logs.get_logger(__name__)
class AIList(LoginRequiredMixin, ObjectList):
list_template = "partials/ai-list.html"
model = AI
page_title = "AIs"
#page_subtitle = "Add times here in order to permit trading."
list_url_name = "ais"
list_url_args = ["type"]
submit_url_name = "ai_create"
class AICreate(LoginRequiredMixin, ObjectCreate):
model = AI
form_class = AIForm
submit_url_name = "ai_create"
class AIUpdate(LoginRequiredMixin, ObjectUpdate):
model = AI
form_class = AIForm
submit_url_name = "ai_update"
class AIDelete(LoginRequiredMixin, ObjectDelete):
model = AI

45
core/views/base.py Normal file
View File

@@ -0,0 +1,45 @@
import logging
# import stripe
from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import JsonResponse
from django.shortcuts import redirect, render
from django.urls import reverse, reverse_lazy
from django.views import View
from django.views.generic.edit import CreateView
from core.forms import NewUserForm
from core.lib.notify import raw_sendmsg
logger = logging.getLogger(__name__)
# Create your views here
class Home(View):
template_name = "index.html"
def get(self, request):
return render(request, self.template_name)
class Signup(CreateView):
form_class = NewUserForm
success_url = reverse_lazy("two_factor:login")
template_name = "registration/signup.html"
def form_valid(self, form):
"""If the form is valid, save the associated model."""
self.object = form.save()
raw_sendmsg(
f"New user signup: {self.object.username} - {self.object.email}",
title="New user",
topic=settings.NOTIFY_TOPIC,
)
return super().form_valid(form)
def get(self, request, *args, **kwargs):
if not settings.REGISTRATION_OPEN:
return render(request, "registration/registration_closed.html")
return super().get(request, *args, **kwargs)

42
core/views/groups.py Normal file
View File

@@ -0,0 +1,42 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from mixins.views import (
ObjectCreate,
ObjectDelete,
ObjectList,
ObjectUpdate,
)
from core.forms import GroupForm
from core.models import Group
from core.util import logs
log = logs.get_logger(__name__)
class GroupList(LoginRequiredMixin, ObjectList):
list_template = "partials/group-list.html"
model = Group
page_title = "Groups"
list_url_name = "groups"
list_url_args = ["type"]
submit_url_name = "group_create"
class GroupCreate(LoginRequiredMixin, ObjectCreate):
model = Group
form_class = GroupForm
submit_url_name = "group_create"
class GroupUpdate(LoginRequiredMixin, ObjectUpdate):
model = Group
form_class = GroupForm
submit_url_name = "group_update"
class GroupDelete(LoginRequiredMixin, ObjectDelete):
model = Group

64
core/views/identifiers.py Normal file
View File

@@ -0,0 +1,64 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from mixins.views import AbortSave, ObjectCreate, ObjectDelete, ObjectList, ObjectUpdate
from django.db import IntegrityError
from core.forms import PersonIdentifierForm
from core.models import PersonIdentifier, Person
from core.util import logs
log = logs.get_logger(__name__)
class IdentifierPermissionMixin:
def set_extra_args(self, user):
self.extra_permission_args = {
"person__user": user,
"person__pk": self.kwargs["person"],
}
class PersonIdentifierList(LoginRequiredMixin, IdentifierPermissionMixin, ObjectList):
list_template = "partials/identifier-list.html"
model = PersonIdentifier
page_title = "Person Identifiers"
list_url_name = "person_identifiers"
list_url_args = ["type", "person"]
submit_url_name = "person_identifier_create"
submit_url_args = ["type", "person"]
class PersonIdentifierCreate(LoginRequiredMixin, IdentifierPermissionMixin, ObjectCreate):
model = PersonIdentifier
form_class = PersonIdentifierForm
submit_url_name = "person_identifier_create"
submit_url_args = ["type", "person"]
def form_valid(self, form):
"""If the form is invalid, render the invalid form."""
try:
return super().form_valid(form)
except IntegrityError as e:
if "UNIQUE constraint failed" in str(e):
form.add_error("identifier", "Identifier rule already exists")
return self.form_invalid(form)
else:
raise e
def pre_save_mutate(self, user, obj):
try:
person = Person.objects.get(pk=self.kwargs["person"], user=user)
obj.person = person
except Person.DoesNotExist:
log.error(f"Person {self.kwargs['person']} does not exist")
raise AbortSave("person does not exist or you don't have access")
class PersonIdentifierUpdate(LoginRequiredMixin, IdentifierPermissionMixin, ObjectUpdate):
model = PersonIdentifier
form_class = PersonIdentifierForm
submit_url_name = "person_identifier_update"
submit_url_args = ["type", "pk", "person"]
class PersonIdentifierDelete(LoginRequiredMixin, IdentifierPermissionMixin, ObjectDelete):
model = PersonIdentifier

View File

@@ -0,0 +1,6 @@
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
class SuperUserRequiredMixin(LoginRequiredMixin, UserPassesTestMixin):
def test_func(self):
return self.request.user.is_superuser

View File

@@ -0,0 +1,42 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from mixins.views import (
ObjectCreate,
ObjectDelete,
ObjectList,
ObjectUpdate,
)
from core.forms import ManipulationForm
from core.models import Manipulation
from core.util import logs
log = logs.get_logger(__name__)
class ManipulationList(LoginRequiredMixin, ObjectList):
list_template = "partials/manipulation-list.html"
model = Manipulation
page_title = "Manipulations"
list_url_name = "manipulations"
list_url_args = ["type"]
submit_url_name = "manipulation_create"
class ManipulationCreate(LoginRequiredMixin, ObjectCreate):
model = Manipulation
form_class = ManipulationForm
submit_url_name = "manipulation_create"
class ManipulationUpdate(LoginRequiredMixin, ObjectUpdate):
model = Manipulation
form_class = ManipulationForm
submit_url_name = "manipulation_update"
class ManipulationDelete(LoginRequiredMixin, ObjectDelete):
model = Manipulation

66
core/views/messages.py Normal file
View File

@@ -0,0 +1,66 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from mixins.views import AbortSave, ObjectCreate, ObjectDelete, ObjectList, ObjectUpdate
from django.db import IntegrityError
from core.forms import MessageForm
from core.models import Message
from core.util import logs
log = logs.get_logger(__name__)
class MessagePermissionMixin:
def set_extra_args(self, user):
self.extra_permission_args = {
"session__user": user,
"session__pk": self.kwargs["session"],
}
class MessageList(LoginRequiredMixin, MessagePermissionMixin, ObjectList):
list_template = "partials/message-list.html"
model = Message
page_title = "Messages"
list_url_name = "messages"
list_url_args = ["type", "session"]
submit_url_name = "message_create"
submit_url_args = ["type", "session"]
class MessageCreate(LoginRequiredMixin, MessagePermissionMixin, ObjectCreate):
model = Message
form_class = MessageForm
submit_url_name = "message_create"
submit_url_args = ["type", "session"]
def form_valid(self, form):
"""If the form is invalid, render the invalid form."""
try:
return super().form_valid(form)
except IntegrityError as e:
if "UNIQUE constraint failed" in str(e):
form.add_error("message", "Identifier rule already exists")
return self.form_invalid(form)
else:
raise e
def pre_save_mutate(self, user, obj):
try:
session = Message.objects.get(pk=self.kwargs["session"], user=user)
obj.session = session
except Message.DoesNotExist:
log.error(f"Session {self.kwargs['session']} does not exist")
raise AbortSave("session does not exist or you don't have access")
class MessageUpdate(LoginRequiredMixin, MessagePermissionMixin, ObjectUpdate):
model = Message
form_class = MessageForm
submit_url_name = "message_update"
submit_url_args = ["type", "pk", "session"]
class MessageDelete(LoginRequiredMixin, MessagePermissionMixin, ObjectDelete):
model = Message

View File

@@ -0,0 +1,30 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from mixins.views import ObjectUpdate
from core.forms import NotificationSettingsForm
from core.models import NotificationSettings
# Notifications - we create a new notification settings object if there isn't one
# Hence, there is only an update view, not a create view.
class NotificationsUpdate(LoginRequiredMixin, ObjectUpdate):
model = NotificationSettings
form_class = NotificationSettingsForm
page_title = "Update your notification settings"
page_subtitle = (
"At least the topic must be set if you want to receive notifications."
)
submit_url_name = "notifications_update"
submit_url_args = ["type"]
pk_required = False
hide_cancel = True
def get_object(self, **kwargs):
notification_settings, _ = NotificationSettings.objects.get_or_create(
user=self.request.user
)
return notification_settings

43
core/views/people.py Normal file
View File

@@ -0,0 +1,43 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from mixins.views import (
ObjectCreate,
ObjectDelete,
ObjectList,
ObjectUpdate,
)
from core.forms import PersonForm
from core.models import Person
from core.util import logs
log = logs.get_logger(__name__)
class PersonList(LoginRequiredMixin, ObjectList):
list_template = "partials/person-list.html"
model = Person
page_title = "People"
#page_subtitle = "Add times here in order to permit trading."
list_url_name = "people"
list_url_args = ["type"]
submit_url_name = "person_create"
class PersonCreate(LoginRequiredMixin, ObjectCreate):
model = Person
form_class = PersonForm
submit_url_name = "person_create"
class PersonUpdate(LoginRequiredMixin, ObjectUpdate):
model = Person
form_class = PersonForm
submit_url_name = "person_update"
class PersonDelete(LoginRequiredMixin, ObjectDelete):
model = Person

42
core/views/personas.py Normal file
View File

@@ -0,0 +1,42 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from mixins.views import (
ObjectCreate,
ObjectDelete,
ObjectList,
ObjectUpdate,
)
from core.forms import PersonaForm
from core.models import Persona
from core.util import logs
log = logs.get_logger(__name__)
class PersonaList(LoginRequiredMixin, ObjectList):
list_template = "partials/persona-list.html"
model = Persona
page_title = "Personas"
list_url_name = "personas"
list_url_args = ["type"]
submit_url_name = "persona_create"
class PersonaCreate(LoginRequiredMixin, ObjectCreate):
model = Persona
form_class = PersonaForm
submit_url_name = "persona_create"
class PersonaUpdate(LoginRequiredMixin, ObjectUpdate):
model = Persona
form_class = PersonaForm
submit_url_name = "persona_update"
class PersonaDelete(LoginRequiredMixin, ObjectDelete):
model = Persona

44
core/views/sessions.py Normal file
View File

@@ -0,0 +1,44 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from mixins.views import (
ObjectCreate,
ObjectDelete,
ObjectList,
ObjectUpdate,
)
from core.forms import SessionForm
from core.models import ChatSession
from core.util import logs
log = logs.get_logger(__name__)
class SessionList(LoginRequiredMixin, ObjectList):
list_template = "partials/session-list.html"
model = ChatSession
page_title = "Chat Sessions"
#page_subtitle = "Add times here in order to permit trading."
list_url_name = "sessions"
list_url_args = ["type"]
submit_url_name = "session_create"
class SessionCreate(LoginRequiredMixin, ObjectCreate):
model = ChatSession
form_class = SessionForm
submit_url_name = "session_create"
class SessionUpdate(LoginRequiredMixin, ObjectUpdate):
model = ChatSession
form_class = SessionForm
submit_url_name = "session_update"
class SessionDelete(LoginRequiredMixin, ObjectDelete):
model = ChatSession

119
core/views/signal.py Normal file
View File

@@ -0,0 +1,119 @@
from core.views.manage.permissions import SuperUserRequiredMixin
from django.views import View
from django.shortcuts import render
import base64
from core.models import Chat
from mixins.views import ObjectRead, ObjectList
import requests
import orjson
class CustomObjectRead(ObjectRead):
def post(self, request, *args, **kwargs):
self.request = request
return super().get(request, *args, **kwargs)
class Signal(SuperUserRequiredMixin, View):
template_name = "pages/signal.html"
def get(self, request):
return render(request, self.template_name)
class SignalAccounts(SuperUserRequiredMixin, ObjectList):
list_template = "partials/signal-accounts.html"
context_object_name_singular = "Signal Account"
context_object_name = "Signal Accounts"
list_url_name = "signal_accounts"
list_url_args = ["type"]
def get_queryset(self, **kwargs):
# url = signal:8080/v1/accounts
url = f"http://signal:8080/v1/accounts"
response = requests.get(url)
accounts = orjson.loads(response.text)
print("ACCOUNTS", accounts)
return accounts
class SignalContactsList(SuperUserRequiredMixin, ObjectList):
list_template = "partials/signal-contacts-list.html"
context_object_name_singular = "Signal Contact"
context_object_name = "Signal Contacts"
list_url_name = "signal_contacts"
list_url_args = ["type", "pk"]
def get_queryset(self, *args, **kwargs):
# url = signal:8080/v1/accounts
print("GET", self.request.GET)
print("KWARGS", self.kwargs)
# /v1/configuration/{number}/settings
# /v1/identities/{number}
# /v1/contacts/{number}
# response = requests.get(f"http://signal:8080/v1/configuration/{self.kwargs['pk']}/settings")
# config = orjson.loads(response.text)
response = requests.get(f"http://signal:8080/v1/identities/{self.kwargs['pk']}")
identities = orjson.loads(response.text)
response = requests.get(f"http://signal:8080/v1/contacts/{self.kwargs['pk']}")
contacts = orjson.loads(response.text)
print("identities", identities)
print("contacts", contacts)
# add identities to contacts
for contact in contacts:
for identity in identities:
if contact["number"] == identity["number"]:
contact["identity"] = identity
obj = {
#"identity": identity,
"contacts": contacts,
}
self.extra_context = {"pretty": list(obj.keys())}
return obj
class SignalChatsList(SuperUserRequiredMixin, ObjectList):
list_template = "partials/signal-chats-list.html"
context_object_name_singular = "Signal Chat"
context_object_name = "Signal Chats"
list_url_name = "signal_chats"
list_url_args = ["type", "pk"]
def get_queryset(self, *args, **kwargs):
pk = self.kwargs.get("pk", "")
object_list = Chat.objects.filter(account=pk)
return object_list
class SignalMessagesList(SuperUserRequiredMixin, ObjectList):
...
class SignalAccountAdd(SuperUserRequiredMixin, CustomObjectRead):
detail_template = "partials/signal-account-add.html"
context_object_name_singular = "Add Account"
context_object_name = "Add Account"
detail_url_name = "signal_account_add"
detail_url_args = ["type", "device"]
page_title = None
def get_object(self, **kwargs):
form_args = self.request.POST.dict()
device_name = form_args["device"]
url = f"http://signal:8080/v1/qrcodelink?device_name={device_name}"
response = requests.get(url)
image_bytes = response.content
base64_image = base64.b64encode(image_bytes).decode("utf-8")
return base64_image