first push

This commit is contained in:
2026-01-18 12:05:56 +03:30
commit cdbb2e11ed
109 changed files with 3083 additions and 0 deletions

0
Notification/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

3
Notification/admin.py Normal file
View File

@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
Notification/apps.py Normal file
View File

@@ -0,0 +1,6 @@
from django.apps import AppConfig
class NotificationConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'Notification'

View File

@@ -0,0 +1,80 @@
# Generated by Django 3.2.13 on 2023-09-17 15:05
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('auth', '0012_alter_user_first_name_max_length'),
]
operations = [
migrations.CreateModel(
name='NotificationType',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('key', models.UUIDField(default=uuid.uuid4, editable=False, null=True, unique=True)),
('create_date', models.DateTimeField(auto_now_add=True)),
('modify_date', models.DateTimeField(auto_now=True)),
('trash', models.BooleanField(default=False)),
('name', models.CharField(choices=[('user', 'USER'), ('alluser', 'AllUSER'), ('group', 'GROUP'), ('allgroup', 'AllGROUP'), ('usergroup', 'UserGroup'), ('poultry', 'Poultry'), ('province_accept', 'ProvinceAccept'), ('province_rejected', 'ProvinceRejected'), ('city_operator_accept', 'CityOperatorAccept'), ('city_operator_rejected', 'CityOperatorRejected'), ('assignment_accepted', 'AssignmentAccepted'), ('assignment_rejected', 'AssignmentRejected')], default='', max_length=50, null=True)),
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='notificationtype_createdby', to=settings.AUTH_USER_MODEL)),
('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='notificationtype_modifiedby', to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='NotificationToken',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('key', models.UUIDField(default=uuid.uuid4, editable=False, null=True, unique=True)),
('create_date', models.DateTimeField(auto_now_add=True)),
('modify_date', models.DateTimeField(auto_now=True)),
('trash', models.BooleanField(default=False)),
('token', models.CharField(max_length=100)),
('app_name', models.CharField(max_length=100, null=True)),
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='notificationtoken_createdby', to=settings.AUTH_USER_MODEL)),
('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='notificationtoken_modifiedby', to=settings.AUTH_USER_MODEL)),
('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='notification_user', to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Notification',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('key', models.UUIDField(default=uuid.uuid4, editable=False, null=True, unique=True)),
('create_date', models.DateTimeField(auto_now_add=True)),
('modify_date', models.DateTimeField(auto_now=True)),
('trash', models.BooleanField(default=False)),
('title', models.CharField(default='', max_length=200, null=True)),
('content', models.CharField(default='', max_length=500, null=True)),
('image', models.CharField(max_length=100, null=True)),
('icon', models.CharField(max_length=100, null=True)),
('app_ids', models.CharField(default='', max_length=200, null=True)),
('device_ids', models.CharField(default='', max_length=200, null=True)),
('hash_id', models.CharField(default='', max_length=20, null=True)),
('status', models.CharField(choices=[('read', 'Read'), ('pending', 'Pending'), ('sent', 'Sent'), ('unread', 'Unread'), ('silent', 'Silent')], default='', max_length=10, null=True)),
('app_name', models.CharField(max_length=100, null=True)),
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='notification_createdby', to=settings.AUTH_USER_MODEL)),
('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='notification_modifiedby', to=settings.AUTH_USER_MODEL)),
('notif_type', models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='types', to='Notification.notificationtype')),
('notification_group', models.ManyToManyField(null=True, related_name='group', to='auth.Group')),
('notification_user', models.ManyToManyField(null=True, related_name='notification_token', to='Notification.NotificationToken')),
],
options={
'abstract': False,
},
),
]

View File

89
Notification/models.py Normal file
View File

@@ -0,0 +1,89 @@
from django.contrib.auth.models import User, Group
from Core.models import BaseModel
from django.db import models
# Create your models here.
class NotificationType(BaseModel):
notif_types = (
("user", "USER"),
("alluser", "AllUSER"),
("group", "GROUP"),
("allgroup", "AllGROUP"),
("usergroup", "UserGroup"),
("poultry", "Poultry"),
("province_accept", "ProvinceAccept"),
("province_rejected", "ProvinceRejected"),
("city_operator_accept", "CityOperatorAccept"),
("city_operator_rejected", "CityOperatorRejected"),
("assignment_accepted", "AssignmentAccepted"),
("assignment_rejected", "AssignmentRejected"),
)
name = models.CharField(choices=notif_types, max_length=50, default="", null=True)
def __str__(self) -> str:
return self.name
def save(self, *args, **kwargs):
super(NotificationType, self).save(*args, **kwargs)
pass
class NotificationToken(BaseModel):
token = models.CharField(max_length=100)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="notification_user", null=True)
app_name = models.CharField(max_length=100, null=True)
def __str__(self) -> str:
return self.token
def save(self, *args, **kwargs):
super(NotificationToken, self).save(*args, **kwargs)
pass
class Notification(BaseModel):
s = (
("read", "Read"),
("pending", "Pending"),
("sent", "Sent"),
("unread", "Unread"),
("silent", "Silent"),
)
notif_type = models.ForeignKey(
NotificationType,
on_delete=models.CASCADE,
null=True,
default=None,
related_name="types",
)
notification_user = models.ManyToManyField(
NotificationToken,
null=True,
related_name="notification_token"
)
notification_group = models.ManyToManyField(
Group,
null=True,
related_name="group"
)
title = models.CharField(max_length=200, default="", null=True)
content = models.CharField(max_length=500, default="", null=True)
image = models.CharField(max_length=100, null=True)
icon = models.CharField(max_length=100, null=True)
app_ids = models.CharField(max_length=200, default="", null=True)
device_ids = models.CharField(max_length=200, default="", null=True)
hash_id = models.CharField(max_length=20, default="", null=True)
status = models.CharField(choices=s, max_length=10, default="", null=True)
app_name = models.CharField(max_length=100, null=True)
def __str__(self) -> str:
return self.title
def save(self, *args, **kwargs):
super(Notification, self).save(*args, **kwargs)
pass

View File

Binary file not shown.

View File

@@ -0,0 +1,17 @@
from django.http.response import JsonResponse
import requests
import json
def get_segments(request):
url = "https://app.najva.com/api/v1/websites/65b3a75a-d634-48c5-824f-c80c703534af/segments/"
headers = {
'content-type': "application/json",
'authorization': "Token 982c17c1d460fec1eef6270c7d6550e3b9b33d2d",
'cache-control': "no-cache",
}
response = requests.request('GET', url=url, headers=headers)
resp = json.loads(response.text.encode('utf8'))
return JsonResponse(resp, safe=False)

View File

@@ -0,0 +1,75 @@
from django.http.response import JsonResponse
from datetime import datetime, timezone, timedelta
import requests
import json
def send_notification_to_all_segments(
title=None,
body=None,
content=None,
icon=None,
image=None,
segments_include=None,
segments_exclude=None,
):
url = "https://app.najva.com/api/v1/notifications/"
payload = {
"api_key": "65b3a75a-d634-48c5-824f-c80c703534af",
"title": "title",
"body": "body",
"priority": "high",
"onclick_action": "open-link",
"url": "https://imedstores.ir/",
"content": "content",
"icon": "",
"image": "",
# "json": "{"key":"value"}",
"sent_time": datetime.now() + timedelta(minutes=1),
"segments_include": [],
"segments_exclude": [],
"one_signal_enabled": False,
"one_signal_accounts": []
}
headers = {
'authorization': "Token 982c17c1d460fec1eef6270c7d6550e3b9b33d2d",
'content-type': "application/json",
'cache-control': "no-cache",
}
response = requests.request("POST", url, data=json.dumps(payload, default=str), headers=headers)
resp = json.loads(response.text.encode('utf-8'))
return resp
def send_notification_to_specific_segment(
title="سامانه سبحان طیور",
body="خوش آمدید",
content="سامانه مدیریت درخواست های مرغداران",
icon="https://user-image-gallery.s3.ir-thr-at1.arvanstorage.com/1WGPTMFND3TREWD.jpg",
image="https://user-image-gallery.s3.ir-thr-at1.arvanstorage.com/1WGPTMFND3TREWD.jpg",
subscriber_tokens=None,
):
url = "https://app.najva.com/notification/api/v1/notifications/"
payload = {
"api_key": "65b3a75a-d634-48c5-824f-c80c703534af",
"subscriber_tokens": subscriber_tokens,
"title": title,
"body": body,
"onclick_action": "open-link",
"url": "https://imedstores.ir/",
"content": content,
"icon": icon,
"image": image,
"sent_time": datetime.now() + timedelta(minutes=3),
}
headers = {
'authorization': "Token 982c17c1d460fec1eef6270c7d6550e3b9b33d2d",
'content-type': "application/json",
'cache-control': "no-cache",
}
response = requests.request("POST", url, data=json.dumps(payload, default=str), headers=headers)
resp = json.loads(response.text.encode('utf-8'))
return resp

View File

@@ -0,0 +1,18 @@
from rest_framework import serializers
from .models import Notification, NotificationToken
from Authentication.serializers import GroupSerializer
class NotificationTokenSerializer(serializers.ModelSerializer):
class Meta:
Model = NotificationToken
fields = "__all__"
class NotificationSerializer(serializers.ModelSerializer):
notif_user = NotificationTokenSerializer()
notif_group = GroupSerializer()
class Meta:
Model = Notification
fields = "__all__"

3
Notification/tests.py Normal file
View File

@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

12
Notification/urls.py Normal file
View File

@@ -0,0 +1,12 @@
from django.urls import path, include
from rest_framework import routers
from django.conf import settings
import oauth2_provider.views as oauth2_views
from .views import NajvaNotificationViewSet
router = routers.DefaultRouter()
router.register('notification_base', NajvaNotificationViewSet, basename='notification_base')
urlpatterns = [
path('', include(router.urls)),
]

157
Notification/views.py Normal file
View File

@@ -0,0 +1,157 @@
import os
import random
import string
from django.shortcuts import render
from django_filters.rest_framework import DjangoFilterBackend
from Authentication.models import UserIdentity
from rest_framework import viewsets, status
from Core.ArvanStorage.arvan_storage import upload_object
from .models import (
Notification,
NotificationType,
NotificationToken
)
from .najva.send_notif_to_segments import (
send_notification_to_all_segments,
send_notification_to_specific_segment
)
from django.contrib.auth.models import User, Group
from .serializers import (
NotificationTokenSerializer,
NotificationSerializer
)
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
ARVAN_NOTIFICATION_GALLERY_URL = 'https://notification-gallery.s3.ir-thr-at1.arvanstorage.com/'
class NajvaNotificationViewSet(viewsets.ModelViewSet):
queryset = NotificationToken.objects.all()
serializer_class = NotificationSerializer
permission_classes = [AllowAny]
def list(self, request, *args, **kwargs):
if "key" in request.GET:
add_obj = Notification.objects.get(key__exact=request.GET["key"])
serializer = self.serializer_class(add_obj)
return Response(serializer.data, status=status.HTTP_200_OK)
if "read_notif" in request.GET:
add_obj = Notification.objects.filter(
user_id=request.user.id,
status="read",
app_name=request.GET['app_name']
)
query = [x for x in add_obj]
serializer = self.serializer_class(query, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
if "unread_notif" in request.GET:
add_obj = Notification.objects.filter(
user_id=request.user.id,
status="unread",
app_name=request.GET['app_name']
)
query = [x for x in add_obj]
serializer = self.serializer_class(query, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
if "pending_notif" in request.GET:
add_obj = Notification.objects.filter(
user_id=request.user.id,
status="pending",
app_name=request.GET['app_name']
)
query = [x for x in add_obj]
serializer = self.serializer_class(query, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
else:
queryset = Notification.objects.all()
serializer = self.serializer_class(queryset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
def create(self, request, *args, **kwargs):
segments = []
userprofile = User.objects.get(user=request.user)
ran = ''.join(random.choices(string.ascii_uppercase + string.digits, k=15))
notification = Notification()
if 'image' in request.data.keys():
image = request.data['image']
upload_object(
image_data=image,
bucket_name="notification-gallery",
object_name="{0}.jpg".format(str(ran))
)
notification_image = ARVAN_NOTIFICATION_GALLERY_URL + "{0}.jpg".format(str(ran))
os.remove("{0}.jpg".format(str(ran)))
else:
notification_image = ""
if 'icon' in request.data.keys():
icon = request.data['icon']
upload_object(
image_data=icon,
bucket_name="notification-gallery",
object_name="{0}.jpg".format(str(ran))
)
notification_icon = ARVAN_NOTIFICATION_GALLERY_URL + "{0}.jpg".format(str(ran))
os.remove("{0}.jpg".format(str(ran)))
else:
notification_icon = ""
if 'request_type' in request.data.keys():
if request.data['request_type'] == "token":
if not NotificationToken.objects.filter(user=userprofile):
notification = NotificationToken()
notification.token = request.data['token']
notification.user = userprofile
notification.app_name = request.data['app_name']
notification.save()
return Response({"msg": "Done"}, status=status.HTTP_200_OK)
else:
return Response({"msg": "user already has token"}, status=status.HTTP_403_FORBIDDEN)
if 'value' in request.data.keys():
if not request.data['value']:
send_notification = send_notification_to_all_segments(
title=request.data['title'],
body=request.data['body'],
content=request.data['content'],
icon=notification_icon,
image=notification_image,
segments_include=request.data['segments_include'],
segments_exclude=request.data['segments_exclude'],
# subscriber_tokens=['c22206d3-248a-4c81-b7c2-de2cfe5e5766']
# subscriber_tokens=['2cc244fc-1340-4942-bf19-2ba9f66f44e6']
)
notification.notif_type = NotificationType.objects.get(name="alluser")
else:
for key in request.data['value']:
if User.objects.filter(key__exact=key):
notif_user = NotificationToken.objects.get(user__key__exact=key)
segments.append(notif_user.token)
if Group.objects.filter(name__exact=key):
for item in NotificationToken.objects.filter(user__role__name=key):
segments.append(item.token)
send_notification = send_notification_to_specific_segment(
title=request.data['title'],
body=request.data['body'],
content=request.data['content'],
icon=notification_icon,
image=notification_image,
subscriber_tokens=segments
)
notification.notif_type = NotificationType.objects.get(name=request.data['request_type'])
notification.title = request.data['title']
notification.content = request.data['content']
notification.icon = notification_icon
notification.image = notification_image
notification.app_name = request.data['app_name']
notification.save()
if 'value' in request.data.keys():
for key in request.data['value']:
if UserIdentity.objects.filter(key__exact=key):
user = UserIdentity.objects.get(key__exact=key).user
notification.notification_user.add(user)
# elif Group.objects.filter(name__exact=key):
# notification.notification_group.add(Group.objects.get(name__exact=key))
# for item in User.objects.filter(role=Group.objects.get(name__exact=key)):
# notification.notification_user.add(item)
return Response(send_notification)