228 lines
7.6 KiB
Python
228 lines
7.6 KiB
Python
from urllib.parse import urlencode
|
|
|
|
import orjson
|
|
import requests
|
|
from django.conf import settings
|
|
from django.shortcuts import render
|
|
from django.urls import reverse
|
|
from django.views import View
|
|
from mixins.views import ObjectList, ObjectRead
|
|
|
|
from core.clients import transport
|
|
from core.models import Chat, PersonIdentifier
|
|
from core.views.manage.permissions import SuperUserRequiredMixin
|
|
|
|
|
|
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"
|
|
service = "signal"
|
|
page_title = "Signal"
|
|
accounts_url_name = "signal_accounts"
|
|
|
|
def get(self, request):
|
|
return render(
|
|
request,
|
|
self.template_name,
|
|
{
|
|
"service": self.service,
|
|
"service_label": self.page_title,
|
|
"accounts_url_name": self.accounts_url_name,
|
|
},
|
|
)
|
|
|
|
|
|
class SignalAccounts(SuperUserRequiredMixin, ObjectList):
|
|
list_template = "partials/signal-accounts.html"
|
|
service = "signal"
|
|
|
|
context_object_name_singular = "Signal Account"
|
|
context_object_name = "Signal Accounts"
|
|
|
|
list_url_name = "signal_accounts"
|
|
list_url_args = ["type"]
|
|
|
|
def _normalize_accounts(self, rows):
|
|
out = []
|
|
for item in rows or []:
|
|
if isinstance(item, dict):
|
|
value = (
|
|
item.get("number")
|
|
or item.get("id")
|
|
or item.get("jid")
|
|
or item.get("account")
|
|
)
|
|
if value:
|
|
out.append(str(value))
|
|
elif item:
|
|
out.append(str(item))
|
|
return out
|
|
|
|
def _service_context(self, service, label, add_url_name, show_contact_actions):
|
|
return {
|
|
"service": service,
|
|
"service_label": label,
|
|
"account_add_url_name": add_url_name,
|
|
"show_contact_actions": show_contact_actions,
|
|
"contacts_url_name": f"{service}_contacts",
|
|
"chats_url_name": f"{service}_chats",
|
|
"endpoint_base": str(
|
|
getattr(settings, "SIGNAL_HTTP_URL", "http://signal:8080")
|
|
).rstrip("/")
|
|
if service == "signal"
|
|
else "",
|
|
"service_warning": transport.get_service_warning(service),
|
|
}
|
|
|
|
def get_queryset(self, **kwargs):
|
|
self.extra_context = self._service_context(
|
|
service="signal",
|
|
label="Signal",
|
|
add_url_name="signal_account_add",
|
|
show_contact_actions=True,
|
|
)
|
|
return self._normalize_accounts(transport.list_accounts("signal"))
|
|
|
|
|
|
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
|
|
# /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)
|
|
|
|
base = getattr(settings, "SIGNAL_HTTP_URL", "http://signal:8080").rstrip("/")
|
|
response = requests.get(f"{base}/v1/identities/{self.kwargs['pk']}")
|
|
identities = orjson.loads(response.text)
|
|
|
|
response = requests.get(f"{base}/v1/contacts/{self.kwargs['pk']}")
|
|
contacts = orjson.loads(response.text)
|
|
|
|
# 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", "")
|
|
chats = list(Chat.objects.filter(account=pk))
|
|
rows = []
|
|
for chat in chats:
|
|
identifier_candidates = [
|
|
str(chat.source_uuid or "").strip(),
|
|
str(chat.source_number or "").strip(),
|
|
]
|
|
identifier_candidates = [value for value in identifier_candidates if value]
|
|
person_identifier = None
|
|
if identifier_candidates:
|
|
person_identifier = (
|
|
PersonIdentifier.objects.filter(
|
|
user=self.request.user,
|
|
service="signal",
|
|
identifier__in=identifier_candidates,
|
|
)
|
|
.select_related("person")
|
|
.first()
|
|
)
|
|
|
|
identifier_value = (
|
|
person_identifier.identifier if person_identifier else ""
|
|
) or (chat.source_uuid or chat.source_number or "")
|
|
service = "signal"
|
|
compose_page_url = ""
|
|
compose_widget_url = ""
|
|
if identifier_value:
|
|
query = f"service={service}&identifier={identifier_value}"
|
|
if person_identifier:
|
|
query += f"&person={person_identifier.person_id}"
|
|
compose_page_url = f"{reverse('compose_page')}?{query}"
|
|
compose_widget_url = f"{reverse('compose_widget')}?{query}"
|
|
if person_identifier:
|
|
ai_url = (
|
|
f"{reverse('ai_workspace')}?person={person_identifier.person_id}"
|
|
)
|
|
else:
|
|
ai_url = reverse("ai_workspace")
|
|
|
|
rows.append(
|
|
{
|
|
"chat": chat,
|
|
"compose_page_url": compose_page_url,
|
|
"compose_widget_url": compose_widget_url,
|
|
"ai_url": ai_url,
|
|
"person_name": (
|
|
person_identifier.person.name if person_identifier else ""
|
|
),
|
|
"manual_icon_class": "fa-solid fa-paper-plane",
|
|
"can_compose": bool(compose_page_url),
|
|
"match_url": (
|
|
f"{reverse('compose_contact_match')}?"
|
|
f"{urlencode({'service': 'signal', 'identifier': identifier_value})}"
|
|
if identifier_value
|
|
else reverse("compose_contact_match")
|
|
),
|
|
}
|
|
)
|
|
return rows
|
|
|
|
|
|
class SignalMessagesList(SuperUserRequiredMixin, ObjectList):
|
|
...
|
|
|
|
|
|
class SignalAccountAdd(SuperUserRequiredMixin, CustomObjectRead):
|
|
detail_template = "partials/signal-account-add.html"
|
|
service = "signal"
|
|
|
|
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"]
|
|
image_bytes = transport.get_link_qr(self.service, device_name)
|
|
base64_image = transport.image_bytes_to_base64(image_bytes)
|
|
|
|
return base64_image
|