Implement AI workspace and mitigation workflow
This commit is contained in:
@@ -1,11 +1,5 @@
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
|
||||
from mixins.views import (
|
||||
ObjectCreate,
|
||||
ObjectDelete,
|
||||
ObjectList,
|
||||
ObjectUpdate,
|
||||
)
|
||||
from mixins.views import ObjectCreate, ObjectDelete, ObjectList, ObjectUpdate
|
||||
|
||||
from core.forms import AIForm
|
||||
from core.models import AI
|
||||
@@ -13,11 +7,12 @@ 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."
|
||||
# page_subtitle = "Add times here in order to permit trading."
|
||||
|
||||
list_url_name = "ais"
|
||||
list_url_args = ["type"]
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
|
||||
from mixins.views import (
|
||||
ObjectCreate,
|
||||
ObjectDelete,
|
||||
ObjectList,
|
||||
ObjectUpdate,
|
||||
)
|
||||
from mixins.views import ObjectCreate, ObjectDelete, ObjectList, ObjectUpdate
|
||||
|
||||
from core.forms import GroupForm
|
||||
from core.models import Group
|
||||
@@ -13,6 +7,7 @@ from core.util import logs
|
||||
|
||||
log = logs.get_logger(__name__)
|
||||
|
||||
|
||||
class GroupList(LoginRequiredMixin, ObjectList):
|
||||
list_template = "partials/group-list.html"
|
||||
model = Group
|
||||
@@ -39,4 +34,4 @@ class GroupUpdate(LoginRequiredMixin, ObjectUpdate):
|
||||
|
||||
|
||||
class GroupDelete(LoginRequiredMixin, ObjectDelete):
|
||||
model = Group
|
||||
model = Group
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from mixins.views import AbortSave, ObjectCreate, ObjectDelete, ObjectList, ObjectUpdate
|
||||
from django.db import IntegrityError
|
||||
from mixins.views import AbortSave, ObjectCreate, ObjectDelete, ObjectList, ObjectUpdate
|
||||
|
||||
from core.forms import PersonIdentifierForm
|
||||
from core.models import PersonIdentifier, Person
|
||||
from core.models import Person, PersonIdentifier
|
||||
from core.util import logs
|
||||
|
||||
log = logs.get_logger(__name__)
|
||||
|
||||
|
||||
class IdentifierPermissionMixin:
|
||||
def set_extra_args(self, user):
|
||||
self.extra_permission_args = {
|
||||
@@ -14,6 +16,7 @@ class IdentifierPermissionMixin:
|
||||
"person__pk": self.kwargs["person"],
|
||||
}
|
||||
|
||||
|
||||
class PersonIdentifierList(LoginRequiredMixin, IdentifierPermissionMixin, ObjectList):
|
||||
list_template = "partials/identifier-list.html"
|
||||
model = PersonIdentifier
|
||||
@@ -26,7 +29,9 @@ class PersonIdentifierList(LoginRequiredMixin, IdentifierPermissionMixin, Object
|
||||
submit_url_args = ["type", "person"]
|
||||
|
||||
|
||||
class PersonIdentifierCreate(LoginRequiredMixin, IdentifierPermissionMixin, ObjectCreate):
|
||||
class PersonIdentifierCreate(
|
||||
LoginRequiredMixin, IdentifierPermissionMixin, ObjectCreate
|
||||
):
|
||||
model = PersonIdentifier
|
||||
form_class = PersonIdentifierForm
|
||||
|
||||
@@ -52,7 +57,10 @@ class PersonIdentifierCreate(LoginRequiredMixin, IdentifierPermissionMixin, Obje
|
||||
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):
|
||||
|
||||
class PersonIdentifierUpdate(
|
||||
LoginRequiredMixin, IdentifierPermissionMixin, ObjectUpdate
|
||||
):
|
||||
model = PersonIdentifier
|
||||
form_class = PersonIdentifierForm
|
||||
|
||||
@@ -60,5 +68,7 @@ class PersonIdentifierUpdate(LoginRequiredMixin, IdentifierPermissionMixin, Obje
|
||||
submit_url_args = ["type", "pk", "person"]
|
||||
|
||||
|
||||
class PersonIdentifierDelete(LoginRequiredMixin, IdentifierPermissionMixin, ObjectDelete):
|
||||
model = PersonIdentifier
|
||||
class PersonIdentifierDelete(
|
||||
LoginRequiredMixin, IdentifierPermissionMixin, ObjectDelete
|
||||
):
|
||||
model = PersonIdentifier
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
|
||||
from mixins.views import (
|
||||
ObjectCreate,
|
||||
ObjectDelete,
|
||||
ObjectList,
|
||||
ObjectUpdate,
|
||||
)
|
||||
from mixins.views import ObjectCreate, ObjectDelete, ObjectList, ObjectUpdate
|
||||
|
||||
from core.forms import ManipulationForm
|
||||
from core.models import Manipulation
|
||||
@@ -13,6 +7,7 @@ from core.util import logs
|
||||
|
||||
log = logs.get_logger(__name__)
|
||||
|
||||
|
||||
class ManipulationList(LoginRequiredMixin, ObjectList):
|
||||
list_template = "partials/manipulation-list.html"
|
||||
model = Manipulation
|
||||
@@ -39,4 +34,4 @@ class ManipulationUpdate(LoginRequiredMixin, ObjectUpdate):
|
||||
|
||||
|
||||
class ManipulationDelete(LoginRequiredMixin, ObjectDelete):
|
||||
model = Manipulation
|
||||
model = Manipulation
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from mixins.views import AbortSave, ObjectCreate, ObjectDelete, ObjectList, ObjectUpdate
|
||||
from django.db import IntegrityError
|
||||
from mixins.views import AbortSave, ObjectCreate, ObjectDelete, ObjectList, ObjectUpdate
|
||||
|
||||
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 = {
|
||||
@@ -14,6 +16,7 @@ class MessagePermissionMixin:
|
||||
"session__pk": self.kwargs["session"],
|
||||
}
|
||||
|
||||
|
||||
class MessageList(LoginRequiredMixin, MessagePermissionMixin, ObjectList):
|
||||
list_template = "partials/message-list.html"
|
||||
model = Message
|
||||
@@ -52,6 +55,7 @@ class MessageCreate(LoginRequiredMixin, MessagePermissionMixin, ObjectCreate):
|
||||
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
|
||||
@@ -62,5 +66,3 @@ class MessageUpdate(LoginRequiredMixin, MessagePermissionMixin, ObjectUpdate):
|
||||
|
||||
class MessageDelete(LoginRequiredMixin, MessagePermissionMixin, ObjectDelete):
|
||||
model = Message
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
|
||||
from mixins.views import (
|
||||
ObjectCreate,
|
||||
ObjectDelete,
|
||||
ObjectList,
|
||||
ObjectUpdate,
|
||||
)
|
||||
from mixins.views import ObjectCreate, ObjectDelete, ObjectList, ObjectUpdate
|
||||
|
||||
from core.forms import PersonForm
|
||||
from core.models import Person
|
||||
@@ -13,11 +7,12 @@ 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."
|
||||
# page_subtitle = "Add times here in order to permit trading."
|
||||
|
||||
list_url_name = "people"
|
||||
list_url_args = ["type"]
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
|
||||
from mixins.views import (
|
||||
ObjectCreate,
|
||||
ObjectDelete,
|
||||
ObjectList,
|
||||
ObjectUpdate,
|
||||
)
|
||||
from mixins.views import ObjectCreate, ObjectDelete, ObjectList, ObjectUpdate
|
||||
|
||||
from core.forms import PersonaForm
|
||||
from core.models import Persona
|
||||
@@ -13,6 +7,7 @@ from core.util import logs
|
||||
|
||||
log = logs.get_logger(__name__)
|
||||
|
||||
|
||||
class PersonaList(LoginRequiredMixin, ObjectList):
|
||||
list_template = "partials/persona-list.html"
|
||||
model = Persona
|
||||
@@ -39,4 +34,4 @@ class PersonaUpdate(LoginRequiredMixin, ObjectUpdate):
|
||||
|
||||
|
||||
class PersonaDelete(LoginRequiredMixin, ObjectDelete):
|
||||
model = Persona
|
||||
model = Persona
|
||||
|
||||
@@ -1,56 +1,63 @@
|
||||
from rest_framework.views import APIView
|
||||
from asgiref.sync import async_to_sync
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
|
||||
from rest_framework import status
|
||||
|
||||
from django.db import transaction
|
||||
from django.http import HttpResponse
|
||||
from core.models import QueuedMessage, Message
|
||||
from mixins.views import ObjectCreate, ObjectDelete, ObjectList, ObjectUpdate
|
||||
from rest_framework import status
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from core.clients import signalapi
|
||||
from core.forms import QueueForm
|
||||
from core.models import Message, QueuedMessage
|
||||
from core.util import logs
|
||||
|
||||
import requests
|
||||
import orjson
|
||||
from django.conf import settings
|
||||
import redis
|
||||
import msgpack
|
||||
|
||||
from mixins.views import (
|
||||
ObjectCreate,
|
||||
ObjectDelete,
|
||||
ObjectList,
|
||||
ObjectUpdate,
|
||||
)
|
||||
|
||||
# def start_typing(uuid):
|
||||
# url = f"http://signal:8080/v1/typing_indicator/{settings.SIGNAL_NUMBER}"
|
||||
# data = {
|
||||
# "recipient": uuid,
|
||||
# }
|
||||
|
||||
# response = requests.put(url, json=data)
|
||||
|
||||
# def stop_typing(uuid):
|
||||
# url = f"http://signal:8080/v1/typing_indicator/{settings.SIGNAL_NUMBER}"
|
||||
# data = {
|
||||
# "recipient": uuid,
|
||||
# }
|
||||
|
||||
# response = requests.delete(url, json=data)
|
||||
|
||||
r = redis.from_url("unix://var/run/gia-redis.sock", db=10)
|
||||
log = logs.get_logger("queue")
|
||||
|
||||
|
||||
class AcceptMessageAPI(LoginRequiredMixin, APIView):
|
||||
def get(self, request, message_id):
|
||||
to_submit = {
|
||||
"type": "def",
|
||||
"method": "accept_message",
|
||||
"user_id": request.user.id,
|
||||
"message_id": message_id,
|
||||
}
|
||||
packed = msgpack.packb(to_submit, use_bin_type=True)
|
||||
r.publish("processing", packed)
|
||||
try:
|
||||
queued = QueuedMessage.objects.select_related(
|
||||
"session",
|
||||
"session__identifier",
|
||||
"session__user",
|
||||
).get(
|
||||
user=request.user,
|
||||
id=message_id,
|
||||
)
|
||||
except QueuedMessage.DoesNotExist:
|
||||
return HttpResponse(status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
if queued.session.identifier.service != "signal":
|
||||
log.warning(
|
||||
"Queue accept failed: unsupported service '%s' for queued message %s",
|
||||
queued.session.identifier.service,
|
||||
queued.id,
|
||||
)
|
||||
return HttpResponse(status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
ts = async_to_sync(signalapi.send_message_raw)(
|
||||
queued.session.identifier.identifier,
|
||||
queued.text or "",
|
||||
[],
|
||||
)
|
||||
if not ts:
|
||||
log.error("Queue accept send failed for queued message %s", queued.id)
|
||||
return HttpResponse(status=status.HTTP_502_BAD_GATEWAY)
|
||||
|
||||
with transaction.atomic():
|
||||
Message.objects.create(
|
||||
user=queued.session.user,
|
||||
session=queued.session,
|
||||
custom_author=queued.custom_author or "BOT",
|
||||
text=queued.text,
|
||||
ts=ts,
|
||||
)
|
||||
queued.delete()
|
||||
|
||||
return HttpResponse(status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class RejectMessageAPI(LoginRequiredMixin, APIView):
|
||||
def get(self, request, message_id):
|
||||
try:
|
||||
@@ -64,11 +71,12 @@ class RejectMessageAPI(LoginRequiredMixin, APIView):
|
||||
message.delete()
|
||||
|
||||
return HttpResponse(status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
|
||||
class QueueList(LoginRequiredMixin, ObjectList):
|
||||
list_template = "partials/queue-list.html"
|
||||
model = QueuedMessage
|
||||
page_title = "Queues"
|
||||
page_title = "Queue"
|
||||
|
||||
list_url_name = "queues"
|
||||
list_url_args = ["type"]
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
|
||||
from mixins.views import (
|
||||
ObjectCreate,
|
||||
ObjectDelete,
|
||||
ObjectList,
|
||||
ObjectUpdate,
|
||||
)
|
||||
from mixins.views import ObjectCreate, ObjectDelete, ObjectList, ObjectUpdate
|
||||
|
||||
from core.forms import SessionForm
|
||||
from core.models import ChatSession
|
||||
@@ -13,11 +7,12 @@ 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."
|
||||
# page_subtitle = "Add times here in order to permit trading."
|
||||
|
||||
list_url_name = "sessions"
|
||||
list_url_args = ["type"]
|
||||
@@ -41,4 +36,3 @@ class SessionUpdate(LoginRequiredMixin, ObjectUpdate):
|
||||
|
||||
class SessionDelete(LoginRequiredMixin, ObjectDelete):
|
||||
model = ChatSession
|
||||
|
||||
|
||||
@@ -1,24 +1,28 @@
|
||||
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
|
||||
import requests
|
||||
from django.shortcuts import render
|
||||
from django.views import View
|
||||
from mixins.views import ObjectList, ObjectRead
|
||||
|
||||
from core.models import Chat
|
||||
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"
|
||||
|
||||
def get(self, request):
|
||||
return render(request, self.template_name)
|
||||
|
||||
|
||||
class SignalAccounts(SuperUserRequiredMixin, ObjectList):
|
||||
list_template = "partials/signal-accounts.html"
|
||||
|
||||
@@ -36,6 +40,7 @@ class SignalAccounts(SuperUserRequiredMixin, ObjectList):
|
||||
|
||||
return accounts
|
||||
|
||||
|
||||
class SignalContactsList(SuperUserRequiredMixin, ObjectList):
|
||||
list_template = "partials/signal-contacts-list.html"
|
||||
|
||||
@@ -45,7 +50,6 @@ class SignalContactsList(SuperUserRequiredMixin, ObjectList):
|
||||
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
|
||||
@@ -67,13 +71,14 @@ class SignalContactsList(SuperUserRequiredMixin, ObjectList):
|
||||
contact["identity"] = identity
|
||||
|
||||
obj = {
|
||||
#"identity": identity,
|
||||
# "identity": identity,
|
||||
"contacts": contacts,
|
||||
}
|
||||
self.extra_context = {"pretty": list(obj.keys())}
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
class SignalChatsList(SuperUserRequiredMixin, ObjectList):
|
||||
list_template = "partials/signal-chats-list.html"
|
||||
|
||||
@@ -82,15 +87,17 @@ class SignalChatsList(SuperUserRequiredMixin, ObjectList):
|
||||
|
||||
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"
|
||||
|
||||
@@ -107,7 +114,7 @@ class SignalAccountAdd(SuperUserRequiredMixin, CustomObjectRead):
|
||||
device_name = form_args["device"]
|
||||
url = f"http://signal:8080/v1/qrcodelink?device_name={device_name}"
|
||||
response = requests.get(url)
|
||||
image_bytes = response.content
|
||||
image_bytes = response.content
|
||||
base64_image = base64.b64encode(image_bytes).decode("utf-8")
|
||||
|
||||
return base64_image
|
||||
return base64_image
|
||||
|
||||
2864
core/views/workspace.py
Normal file
2864
core/views/workspace.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user