Skip to content

Commit

Permalink
Merge branch 'dev' into paymentsfix
Browse files Browse the repository at this point in the history
  • Loading branch information
KunalTiwary authored May 27, 2024
2 parents 4b97324 + 7cd1089 commit cb83473
Show file tree
Hide file tree
Showing 11 changed files with 487 additions and 34 deletions.
12 changes: 12 additions & 0 deletions backend/dataset/migrations/0046_merge_20240416_2233.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Generated by Django 3.2.14 on 2024-04-16 17:03

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("dataset", "0045_alter_ocrdocument_ocr_domain"),
("dataset", "0045_auto_20240321_0949"),
]

operations = []
15 changes: 14 additions & 1 deletion backend/dataset/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ def download(self, request, pk):
URL: /data/instances/<instance-id>/download/
Accepted methods: GET
"""
export_type = request.GET.get("type", "csv")
export_type = request.GET.get("export_type", "csv").lower()
try:
# Get the dataset instance for the id
dataset_instance = DatasetInstance.objects.get(instance_id=pk)
Expand All @@ -314,6 +314,19 @@ def download(self, request, pk):

dataset_model = apps.get_model("dataset", dataset_instance.dataset_type)
data_items = dataset_model.objects.filter(instance_id=pk)
field_names = set([field.name for field in dataset_model._meta.get_fields()])
for key, value in request.GET.items():
if key in field_names:
kwargs = {f"{key}__icontains": value}
data_items = data_items.filter(**kwargs)
elif key == "export_type":
continue
else:
return Response(
{"message": "The corresponding column does not exist"},
status=status.HTTP_400_BAD_REQUEST,
)

dataset_resource = resources.RESOURCE_MAP[dataset_instance.dataset_type]
exported_items = dataset_resource().export_as_generator(export_type, data_items)
if export_type == "tsv":
Expand Down
150 changes: 137 additions & 13 deletions backend/organizations/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
from shoonya_backend.settings import AUTH_USER_MODEL
from shoonya_backend.mixins import DummyModelMixin
import secrets
from django.core.mail import send_mail
from django.core.mail import EmailMultiAlternatives
import os
from dotenv import load_dotenv


load_dotenv()

from django.conf import settings
Expand Down Expand Up @@ -120,6 +121,139 @@ def __str__(self):
+ " organization"
)

@classmethod
def send_invite_email(cls, invite, user):
current_environment = os.getenv("ENV")
base_url = (
"dev.shoonya.ai4bharat.org"
if current_environment == "dev"
else "shoonya.ai4bharat.org"
)
subject = "Invitation to join Organization"
invite_link = f"https://{base_url}/#/invite/{invite.invite_code}"
text_content = f"Hello! You are invited to Shoonya. Your Invite link is: "
style_string = """
*{ margin: 0;
padding: 0;
}
body {
font-family: "Arial", sans-serif;
background-color: #f2f8f8;
margin: 0;
padding: 0;
padding-top: 2rem;
}
.container {
background-color: #fff;
border: solid 1px #e1e1e1;
border-radius: 2px;
padding: 1.4rem;
max-width: 380px;
margin: auto;
}
.header {
width: fit-content;
margin: auto;
}
h1 {
font-size: 1.2rem;
font-weight: 300;
margin: 1rem 0;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
}
p {
font-size: 0.9rem;
color: #222;
margin: 0.8rem 0;
}
.primary {
color: #18621f;
}
.footer {
margin-top: 1rem;
font-size: 0.9rem;
}
.footer > * {
font-size: inherit;
}"""

html_content = f"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Invitation to join Shoonya Organisation</title>
<style>
{style_string}
</style>
</head>
<body>
<div class="container">
<header class="header">
<h3>Invitaiton to join Shoonya</h3>
</header>
<main>
<div style="margin: 1rem auto; width: fit-content">
<table
width="180"
border="0"
align="center"
cellpadding="0"
cellspacing="0"
>
<tbody>
<tr>
<td
style="
font-size: 12px;
font-family: 'Zurich BT', Tahoma, Helvetica, Arial;
text-align: center;
color: white;
border-radius: 1rem;
border-width: 1px;
background-color: rgb(44, 39, 153);
">
<a target="_blank" style="text-decoration: none; color:white; font-size: 14px; display: block; padding: 0.2rem 0.5rem; " href="{invite_link}">
Join Shoonya Now
</a>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<p>
Please use the above link to verify your email address and complete your registration.
</p>
<p style="font-style: italic">
For security purposes, please do not share the this link with
anyone.
</p>
<p style="font-size: 10px; color:grey">
If clicking the link doesn't work, you can copy and paste the link into your browser's address window, or retype it there.
<a href="{invite_link}">{invite_link}</a>
</p>
</div>
</main>
<footer class="footer">
<p>
Best Regards,<br />
Shoonya Team
</p>
</footer>
</div>
</body>
</html>
"""
msg = EmailMultiAlternatives(
subject, text_content, settings.DEFAULT_FROM_EMAIL, [user.email]
)
msg.attach_alternative(html_content, "text/html")
msg.send()

@classmethod
def create_invite(cls, organization=None, users=None):
with transaction.atomic():
Expand All @@ -130,12 +264,7 @@ def create_invite(cls, organization=None, users=None):
invite = Invite.objects.create(organization=organization, user=user)
invite.invite_code = cls.generate_invite_code()
invite.save()
send_mail(
"Invitation to join Organization",
f"Hello! You are invited to {organization.title}. Your Invite link is: https://shoonya.ai4bharat.org/#/invite/{invite.invite_code}",
settings.DEFAULT_FROM_EMAIL,
[user.email],
)
cls.send_invite_email(invite, user)

# def has_permission(self, user):
# if self.organization.created_by.pk == user.pk or user.is_superuser:
Expand All @@ -147,12 +276,7 @@ def re_invite(cls, users=None):
with transaction.atomic():
for user in users:
invite = Invite.objects.get(user=user)
send_mail(
"Invitation to join Organization",
f"Hello! You are invited to {invite.organization.title}. Your Invite link is: https://shoonya.ai4bharat.org/#/invite/{invite.invite_code}",
settings.DEFAULT_FROM_EMAIL,
[user.email],
)
cls.send_invite_email(invite, user)

@classmethod
def generate_invite_code(cls):
Expand Down
2 changes: 1 addition & 1 deletion backend/projects/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ def create_parameters_for_task_creation(
tasks = create_tasks_from_dataitems(sampled_items, project)


# @shared_task
@shared_task
def export_project_in_place(
annotation_fields, project_id, project_type, get_request_data
) -> None:
Expand Down
6 changes: 4 additions & 2 deletions backend/shoonya_backend/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"shoonya.ai4bharat.org",
"0.0.0.0",
"backend.shoonya.ai4bharat.org",
"backend.shoonya2.ai4bharat.org",
]

# Application definition
Expand Down Expand Up @@ -186,12 +187,13 @@


# Email Settings
EMAIL_BACKEND = "django_smtp_ssl.SSLEmailBackend"
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = os.getenv("EMAIL_HOST")
EMAIL_PORT = 465
EMAIL_PORT = os.getenv("EMAIL_PORT")
EMAIL_HOST_USER = os.getenv("SMTP_USERNAME")
EMAIL_HOST_PASSWORD = os.getenv("SMTP_PASSWORD")
EMAIL_USE_TLS = True
EMAIL_USE_SSL = False
DEFAULT_FROM_EMAIL = os.getenv("DEFAULT_FROM_EMAIL")

DOMAIN = "shoonya.ai4bharat.org"
Expand Down
9 changes: 0 additions & 9 deletions backend/tasks/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1740,15 +1740,6 @@ def partial_update(self, request, pk=None):
if annotation_obj.annotation_status == TO_BE_REVISED:
update_notification(annotation_obj, task)
is_revised = True
print(annotation_obj)
if "ids" in dict(request.data):
pass

else:
return Response(
{"message": "key doesnot match"},
status=status.HTTP_400_BAD_REQUEST,
)

elif annotation_obj.annotation_type == SUPER_CHECKER_ANNOTATION:
is_rejected = False
Expand Down
34 changes: 34 additions & 0 deletions backend/users/migrations/0032_auto_20240417_1028.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Generated by Django 3.2.14 on 2024-04-17 04:58

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):
dependencies = [
("users", "0031_user_notification_limit"),
]

operations = [
migrations.AddField(
model_name="user",
name="approved_by",
field=models.ForeignKey(
blank=True,
default=1,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to=settings.AUTH_USER_MODEL,
),
),
migrations.AddField(
model_name="user",
name="is_approved",
field=models.BooleanField(
default=True,
help_text="Indicates whether user is approved by the admin or not.",
verbose_name="is_approved",
),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 3.2.14 on 2024-04-22 14:02

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("users", "0032_auto_20240417_1028"),
]

operations = [
migrations.RenameField(
model_name="user",
old_name="approved_by",
new_name="invited_by",
),
]
16 changes: 16 additions & 0 deletions backend/users/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,22 @@ class User(AbstractBaseUser, PermissionsMixin):
"Indicates whether user prefers Chitralekha UI for audio transcription tasks or not."
),
)
# def get_default_user():
# return settings.AUTH_USER_MODEL.objects.get(id=1)

is_approved = models.BooleanField(
verbose_name="is_approved",
default=False,
help_text=("Indicates whether user is approved by the admin or not."),
)

invited_by = models.ForeignKey(
"self",
on_delete=models.SET_NULL,
null=True,
blank=True,
default=1,
)

class Meta:
db_table = "user"
Expand Down
29 changes: 29 additions & 0 deletions backend/users/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,35 @@ def update(self, instance, validated_data):
return instance


class UsersPendingSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = [
"id",
"username",
"first_name",
"last_name",
"email",
"role",
"invited_by",
"has_accepted_invite",
]

def update(self, instance, validated_data):
instance.id = validated_data.get("id", instance.id)
instance.username = validated_data.get("username", instance.username)
instance.first_name(validated_data.get("first_name", instance.first_name))
instance.last_name(validated_data.get("last_name", instance.last_name))
instance.email(validated_data.get("email", instance.email))
instance.role(validated_data.get("role", instance.role))
instance.invited_by(validated_data.get("invited_by", instance.invited_by))
instance.has_accepted_invite(
validated_data.get("has_accepted_invite", instance.has_accepted_invite)
)
instance.save()
return instance


class UserUpdateSerializer(serializers.ModelSerializer):
organization = OrganizationSerializer()

Expand Down
Loading

0 comments on commit cb83473

Please sign in to comment.