Skip to content

Commit

Permalink
Merge pull request #393 from Healthlane-Technologies/merge/release_fr…
Browse files Browse the repository at this point in the history
…ontend

frontend merged to release_workflow branch
  • Loading branch information
shahharsh176 authored Sep 27, 2024
2 parents 9def04d + 6ffcd34 commit 3823173
Show file tree
Hide file tree
Showing 37 changed files with 2,316 additions and 60 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/release-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,14 @@ jobs:

- name: Zip repository
run: |
zip -r ${{ inputs.aws-pkg-name }}.zip .
zip -r ${{ inputs.aws-pkg-name }}.zip ${{ inputs.aws-pkg-name }}
- name: Setup AWS CLI
run: |
aws configure set aws_access_key_id ${{ secrets.PKG_S3_ACCESS_KEY_ID }}
aws configure set aws_secret_access_key ${{ secrets.PKG_S3_ACCESS_KEY_SECRET }}
aws configure set region ${{ secrets.PKG_S3_REGION }}
- name: Upload to S3
run: |
aws s3 sync . s3://zelthy3-packages/packages/${{ inputs.aws-pkg-name }}/${{ env.VERSION }}/ --acl public-read --exclude '*' --include '${{ inputs.aws-pkg-name }}.zip'
aws s3 cp '${{ inputs.aws-pkg-name }}.zip' s3://zelthy3-packages/packages/${{ inputs.aws-pkg-name }}/${{ env.VERSION }}/ --acl public-read
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ repos:
- id: check-symlinks
- id: check-toml
- id: end-of-file-fixer
exclude: frontend/
exclude: ^(frontend/|.*\.js$)
- id: requirements-txt-fixer
- id: detect-private-key
- repo: https://github.com/astral-sh/ruff-pre-commit
Expand Down
1 change: 1 addition & 0 deletions backend/requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ django-storages==1.14
django-tenants==3.6.1
djangorestframework==3.15.2
flake8==6.1.0
flower==2.0.1
GitPython==3.1.43
loguru==0.7.2
opentelemetry-api==1.22.0
Expand Down
7 changes: 7 additions & 0 deletions backend/src/zango/api/platform/tenancy/v1/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ def update(self, instance, validated_data):

class AppUserModelSerializerModel(serializers.ModelSerializer):
roles = UserRoleSerializerModel(many=True)
pn_country_code = serializers.SerializerMethodField()

class Meta:
model = AppUserModel
Expand All @@ -104,8 +105,14 @@ class Meta:
"is_active",
"last_login",
"created_at",
"pn_country_code",
]

def get_pn_country_code(self, obj):
if obj.mobile:
return f"+{obj.mobile.country_code}"
return None


class ThemeModelSerializer(serializers.ModelSerializer):
class Meta:
Expand Down
26 changes: 24 additions & 2 deletions backend/src/zango/api/platform/tenancy/v1/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@
from zango.core.api.utils import ZangoAPIPagination
from zango.core.common_utils import set_app_schema_path
from zango.core.permissions import IsPlatformUserAllowedApp
from zango.core.utils import get_search_columns
from zango.core.utils import (
get_country_code_for_tenant,
get_search_columns,
validate_phone,
)

from .serializers import (
AppUserModelSerializerModel,
Expand Down Expand Up @@ -340,6 +344,10 @@ class UserViewAPIV1(ZangoGenericPlatformAPIView, ZangoAPIPagination):
pagination_class = ZangoAPIPagination
permission_classes = (IsPlatformUserAllowedApp,)

def get_app_tenant(self):
tenant_obj = TenantModel.objects.get(uuid=self.kwargs["app_uuid"])
return tenant_obj

def get_dropdown_options(self):
options = {}
options["roles"] = [
Expand Down Expand Up @@ -386,10 +394,12 @@ def get(self, request, *args, **kwargs):
app_users = self.paginate_queryset(app_users, request, view=self)
serializer = AppUserModelSerializerModel(app_users, many=True)
app_users_data = self.get_paginated_response_data(serializer.data)
app_tenant = self.get_app_tenant()
success = True
response = {
"users": app_users_data,
"message": "Users fetched successfully",
"pn_country_code": get_country_code_for_tenant(app_tenant),
}
if include_dropdown_options:
response["dropdown_options"] = self.get_dropdown_options()
Expand All @@ -406,6 +416,10 @@ def post(self, request, *args, **kwargs):
data = request.data
try:
role_ids = data.getlist("roles")
if data.get("mobile"):
if not validate_phone(data["mobile"]):
result = {"message": "Invalid mobile number"}
return get_api_response(False, result, 400)
creation_result = AppUserModel.create_user(
name=data["name"],
email=data["email"],
Expand Down Expand Up @@ -437,7 +451,10 @@ def get(self, request, *args, **kwargs):
obj = self.get_obj(**kwargs)
serializer = AppUserModelSerializerModel(obj)
success = True
response = {"user": serializer.data}
response = {
"user": serializer.data,
"pn_country_code": f"+{obj.mobile.country_code}",
}
status = 200
except Exception as e:
success = False
Expand All @@ -447,7 +464,12 @@ def get(self, request, *args, **kwargs):
return get_api_response(success, response, status)

def put(self, request, *args, **kwargs):
data = request.data
try:
if data.get("mobile"):
if not validate_phone(data["mobile"]):
result = {"message": "Invalid mobile number"}
return get_api_response(False, result, 400)
obj = self.get_obj(**kwargs)
update_result = AppUserModel.update_user(obj, request.data)
success = update_result["success"]
Expand Down
5 changes: 1 addition & 4 deletions backend/src/zango/apps/tasks/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,4 @@ def get_crontab_obj(crontab={}):
"month_of_year": "*",
}

schedule, created = CrontabSchedule.objects.get_or_create(**crontab)
if created:
return schedule, True
return schedule, False
return CrontabSchedule.objects.get_or_create(**crontab)

This file was deleted.

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions backend/src/zango/core/package_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,9 @@ def get_package_configuration_url(request, tenant, package_name):
for route in data["package_routes"]:
if route["package"] == package_name:
domain = tenant.domains.filter(is_primary=True).last()
url = get_current_request_url(request, domain=domain)
return f"{url}/{route['re_path'][1:]}configure/"
if domain:
url = get_current_request_url(request, domain=domain)
return f"{url}/{route['re_path'][1:]}configure/"
return ""


Expand Down
62 changes: 62 additions & 0 deletions backend/src/zango/core/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import json

import phonenumbers
import pytz

from phonenumbers.phonenumberutil import country_code_for_region

from django.conf import settings
from django.db import connection
from django.shortcuts import render
Expand Down Expand Up @@ -120,3 +123,62 @@ def generate_lockout_response(request, credentials):
{"logout_url": "/auth/logout", "cooloff_time": cooloff_time},
status=403,
)


def validate_phone(phone_number, region=None):
"""
Validates a phone number by parsing it and checking if it is a valid phone number for the given region.
Args:
phone_number (str): The phone number to be validated.
region (str, optional): The region in which the phone number is valid. Defaults to None.
Returns:
bool: True if the phone number is valid, False otherwise.
Raises:
None
"""
try:
region = region or settings.PHONENUMBER_DEFAULT_REGION
phone_number = phonenumbers.parse(phone_number, region=region)
if phonenumbers.is_valid_number(phone_number):
return True
except Exception:
return False


def get_region_from_timezone(tzname):
timezone_country = {}
for countrycode in pytz.country_timezones:
timezones = pytz.country_timezones[countrycode]
for tz in timezones:
timezone_country[tz] = countrycode
return timezone_country[tzname]


def get_country_code_for_tenant(tenant, with_plus_sign=True):
"""
Returns the country code for the given tenant.
The region is first determined from the tenant's timezone. If no timezone is set,
the default region from `settings.PHONENUMBER_DEFAULT_REGION` is used.
Args:
tenant: A TenantModel instance.
with_plus_sign (bool): Whether to prepend a "+" to the country code. Default is True.
Returns:
str: The country code with or without "+" based on the region (e.g., "+1" for "US", "+91" for "IN").
"""
default_region = settings.PHONENUMBER_DEFAULT_REGION

if tenant.timezone:
try:
default_region = get_region_from_timezone(tenant.timezone)
except Exception:
pass

country_code = country_code_for_region(default_region)
return f"+{country_code}" if with_plus_sign else country_code
10 changes: 4 additions & 6 deletions backend/src/zango/middleware/tenant.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
from django.utils import timezone
from django.utils.deprecation import MiddlewareMixin

from zango.core.utils import get_region_from_timezone


class ZangoTenantMainMiddleware(TenantMainMiddleware):
TENANT_NOT_FOUND_EXCEPTION = Http404
Expand Down Expand Up @@ -146,12 +148,8 @@ def __call__(self, request):
try:
tzname = request.tenant.timezone
timezone.activate(pytz.timezone(tzname))
timezone_country = {}
for countrycode in pytz.country_timezones:
timezones = pytz.country_timezones[countrycode]
for tz in timezones:
timezone_country[tz] = countrycode
settings.PHONENUMBER_DEFAULT_REGION = timezone_country[tzname]
region = get_region_from_timezone(tzname)
settings.PHONENUMBER_DEFAULT_REGION = region
except Exception:
timezone.deactivate()
return self.get_response(request)
1 change: 1 addition & 0 deletions deploy/dev.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ USER zango_user


COPY init.sh /zango/
COPY start_flower.sh /zango/
WORKDIR /zango/
CMD ["/bin/sh", "init.sh"]
27 changes: 26 additions & 1 deletion deploy/docker_compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,32 @@ services:
redis:
condition: service_healthy

celery-flower:
build:
context: .
dockerfile: dev.dockerfile
args:
- HOST_UID=${HOST_UID}
- HOST_GID=${HOST_GID}
restart: always
entrypoint:
- /bin/sh
- start_flower.sh
ports:
- "5555:5555"
env_file:
- .env
volumes:
- .:/zango/
environment:
- FLOWER_PORT=5555
- FLOWER_PERSISTENT=True
- FLOWER_STATE_SAVE_INTERVAL=10000
depends_on:
- postgres
- redis
- celery

redis:
image: redis
ports:
Expand All @@ -83,6 +109,5 @@ services:
redis:
condition: service_healthy


volumes:
dev_db:
26 changes: 26 additions & 0 deletions deploy/docker_compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,32 @@ services:
timeout: 5s
retries: 3

celery-flower:
build:
context: .
dockerfile: prod.dockerfile
args:
- HOST_UID=${HOST_UID}
- HOST_GID=${HOST_GID}
restart: always
entrypoint:
- /bin/sh
- start_flower.sh
ports:
- "5555:5555"
env_file:
- .env
volumes:
- .:/zango/
environment:
- FLOWER_PORT=5555
- FLOWER_PERSISTENT=True
- FLOWER_STATE_SAVE_INTERVAL=10000
depends_on:
- postgres
- redis
- celery

celery_beat:
image: kczelthy/zango:latest
command: /bin/sh -c "cd ${PROJECT_NAME} && celery -A ${PROJECT_NAME} beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler"
Expand Down
1 change: 1 addition & 0 deletions deploy/prod.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ RUN apt update && \
USER zango_user

COPY init.sh /zango/
COPY start_flower.sh /zango/
WORKDIR /zango/
CMD ["/bin/sh", "init.sh"]
9 changes: 9 additions & 0 deletions deploy/start_flower.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh

cd ${PROJECT_NAME}
until timeout 5s celery -A ${PROJECT_NAME} inspect ping; do
>&2 echo "Celery workers not available"
done

echo 'Starting flower'
celery -A ${PROJECT_NAME} flower --port=5555
Loading

0 comments on commit 3823173

Please sign in to comment.