commit 85c76a2bc67ff490ce5d8f8ee626da433bbd1334 Author: Sayyid Hamid Mahdavi Date: Sat May 10 11:52:08 2025 +0330 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ee024d2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea +.env +media +/clients/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1136345 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ +FROM debian:12 +ENV PYTHONUNBUFFERED 1 +WORKDIR /app +#RUN date +RUN apt update +RUN apt install gnupg2 netcat-traditional libssl-dev libcrypto++-dev lsb-release python3-pip -y +RUN apt install binutils libproj-dev gdal-bin -y +COPY requirements.txt /app/requirements.txt +RUN pip3 install --break-system-packages -r requirements.txt +#ENTRYPOINT ["./run.sh"] diff --git a/manage.py b/manage.py new file mode 100755 index 0000000..fbda2b3 --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'main.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/requirements.in b/requirements.in new file mode 100644 index 0000000..47bd1bb --- /dev/null +++ b/requirements.in @@ -0,0 +1,19 @@ +Django +python-decouple +psycopg[binary,pool] +django-jalali-date +django-crispy-forms +crispy_bootstrap5 +djangorestframework +django-filter +django-cors-headers +gunicorn +gevent +drf-spectacular +pillow +requests +django-oauth-toolkit +redis +celery +httpx +django-redis \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..fb0e1f6 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,184 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile +# +amqp==5.3.1 + # via kombu +anyio==4.8.0 + # via httpx +asgiref==3.8.1 + # via + # django + # django-cors-headers +async-timeout==5.0.1 + # via redis +attrs==24.3.0 + # via + # jsonschema + # referencing +billiard==4.2.1 + # via celery +celery==5.4.0 + # via -r requirements.in +certifi==2024.12.14 + # via + # httpcore + # httpx + # requests +cffi==1.17.1 + # via cryptography +charset-normalizer==3.4.0 + # via requests +click==8.1.7 + # via + # celery + # click-didyoumean + # click-plugins + # click-repl +click-didyoumean==0.3.1 + # via celery +click-plugins==1.1.1 + # via celery +click-repl==0.3.0 + # via celery +crispy-bootstrap5==2024.10 + # via -r requirements.in +cryptography==44.0.0 + # via jwcrypto +django==5.1.4 + # via + # -r requirements.in + # crispy-bootstrap5 + # django-cors-headers + # django-crispy-forms + # django-filter + # django-jalali-date + # django-oauth-toolkit + # django-redis + # djangorestframework + # drf-spectacular +django-cors-headers==4.6.0 + # via -r requirements.in +django-crispy-forms==2.3 + # via + # -r requirements.in + # crispy-bootstrap5 +django-filter==24.3 + # via -r requirements.in +django-jalali-date==1.1.3 + # via -r requirements.in +django-oauth-toolkit==3.0.1 + # via -r requirements.in +django-redis==5.4.0 + # via -r requirements.in +djangorestframework==3.15.2 + # via + # -r requirements.in + # drf-spectacular +drf-spectacular==0.28.0 + # via -r requirements.in +gevent==24.11.1 + # via -r requirements.in +greenlet==3.1.1 + # via gevent +gunicorn==23.0.0 + # via -r requirements.in +h11==0.14.0 + # via httpcore +httpcore==1.0.7 + # via httpx +httpx==0.28.1 + # via -r requirements.in +idna==3.10 + # via + # anyio + # httpx + # requests +inflection==0.5.1 + # via drf-spectacular +jalali-core==1.0.0 + # via jdatetime +jdatetime==5.0.0 + # via django-jalali-date +jsonschema==4.23.0 + # via drf-spectacular +jsonschema-specifications==2024.10.1 + # via jsonschema +jwcrypto==1.5.6 + # via django-oauth-toolkit +kombu==5.4.2 + # via celery +oauthlib==3.2.2 + # via django-oauth-toolkit +packaging==24.2 + # via gunicorn +pillow==11.0.0 + # via -r requirements.in +prompt-toolkit==3.0.48 + # via click-repl +psycopg[binary,pool]==3.2.3 + # via -r requirements.in +psycopg-binary==3.2.3 + # via psycopg +psycopg-pool==3.2.4 + # via psycopg +pycparser==2.22 + # via cffi +python-dateutil==2.9.0.post0 + # via celery +python-decouple==3.8 + # via -r requirements.in +pyyaml==6.0.2 + # via drf-spectacular +redis==5.2.1 + # via + # -r requirements.in + # django-redis +referencing==0.35.1 + # via + # jsonschema + # jsonschema-specifications +requests==2.32.3 + # via + # -r requirements.in + # django-oauth-toolkit +rpds-py==0.22.3 + # via + # jsonschema + # referencing +six==1.17.0 + # via python-dateutil +sniffio==1.3.1 + # via anyio +sqlparse==0.5.3 + # via django +typing-extensions==4.12.2 + # via + # anyio + # jwcrypto + # psycopg + # psycopg-pool +tzdata==2024.2 + # via + # celery + # kombu +uritemplate==4.1.1 + # via drf-spectacular +urllib3==2.2.3 + # via requests +vine==5.1.0 + # via + # amqp + # celery + # kombu +wcwidth==0.2.13 + # via prompt-toolkit +zope-event==5.0 + # via gevent +zope-interface==7.2 + # via gevent + +# The following packages are considered to be unsafe in a requirements file: +# setuptools diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..2ebdb8a --- /dev/null +++ b/run.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +while ! nc -z $DB_HOST 5432 ; do + echo "APP Waiting for the DB Server" + sleep 3 +done +#python3 manage.py collectstatic --noinput +python3 manage.py migrate +gunicorn main.wsgi:application --bind 0.0.0.0:8000 -w 4 \ No newline at end of file diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..b071535 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,125 @@ +{% load static %} +{#{% load view_breadcrumbs %}#} + + + + + + + + + {% block title %}welcome{% endblock %} + + + + + + + + + + {# #} + + + + + + + + + + + +
+
+ {# {% include "include/sidebar.html" %}#} +
+
+
+
+ {% include "include/top_bar.html" %} + {% include "include/messages.html" %} + {# {% block breadcrumbs %}#} + {# {% render_breadcrumbs %}#} + {# {% endblock %}#} + +
+
+
+
+

+ {% block page_title %} + {% endblock %} +

+
+
+
+
+
+
+ {% block page_action %} + {% endblock %} +
+
+
+
+ +
+ +
+
+
+
+
+ {% block content %} + {% endblock %} +
+
+
+
+
+ + + {# {% include 'include/footer.html' %}#} + +
+
+ + +
+
+
+ + + + + + + diff --git a/templates/core/home.html b/templates/core/home.html new file mode 100644 index 0000000..c0a2b96 --- /dev/null +++ b/templates/core/home.html @@ -0,0 +1,12 @@ +{% extends "base.html" %} +{% load static %} +{% load crispy_forms_tags %} +{% load jalali_tags %} + +{% block title %}IPG: Home{% endblock %} +{% block page_title %}IPG: Home{% endblock %} + + +{% block content %} + IPG +{% endblock %} \ No newline at end of file diff --git a/templates/include/filter_action.html b/templates/include/filter_action.html new file mode 100644 index 0000000..f71ec68 --- /dev/null +++ b/templates/include/filter_action.html @@ -0,0 +1,33 @@ +{% load crispy_forms_tags %} + + + + + diff --git a/templates/include/messages.html b/templates/include/messages.html new file mode 100644 index 0000000..158837d --- /dev/null +++ b/templates/include/messages.html @@ -0,0 +1,9 @@ +{% if messages %} + {% for message in messages %} +{# #} + + {% endfor %} +{% endif %} diff --git a/templates/include/paginator.html b/templates/include/paginator.html new file mode 100644 index 0000000..b2a452a --- /dev/null +++ b/templates/include/paginator.html @@ -0,0 +1,21 @@ +{% load tags %} + + diff --git a/templates/include/top_bar.html b/templates/include/top_bar.html new file mode 100644 index 0000000..c42e2c9 --- /dev/null +++ b/templates/include/top_bar.html @@ -0,0 +1,21 @@ +{% load static %} + + +
+
+
+
+
+ {# #} + +
+ +
+
+ {# #} + +
+
+
+
+
diff --git a/utils/wallet_client.py b/utils/wallet_client.py new file mode 100644 index 0000000..e5ae9bf --- /dev/null +++ b/utils/wallet_client.py @@ -0,0 +1,123 @@ +import time + +import requests +from django.conf import settings +from django.core.cache import cache +from django.db import models +from httpx import Request + +from gooyal_wallet_client import AuthenticatedClient +from gooyal_wallet_client.models import MyWallet, UserTransaction, ApplicationDeposit, ApplicationWithdraw +from gooyal_wallet_client.api.wallet import (wallet_api_application_deposit_create, + wallet_api_application_deposit_verify_retrieve, + wallet_api_application_withdraw_create, + wallet_api_application_withdraw_verify_retrieve) +from gooyal_wallet_client.types import Response + + +class ContentTypeChoices(models.IntegerChoices): + IMAGE = 1, 'image' + VOICE = 2, 'voice' + VIDEO = 3, 'video' + + +def login_as_client_credentials(): + access_token = cache.get('ads_access_token') + # expires_in = self.auth_data.get('expires_in') + # created_at = self.auth_data.get('created_at') + # + # if access_token and expires_in > time.time() - created_at: + # return self.auth_data + if access_token: + print('already in cache') + return access_token + + print('not in cache') + + data = { + "grant_type": 'client_credentials', + "scope": settings.SCOPES, + } + auth = (settings.CLIENT_ID, settings.CLIENT_SECRET) + + response = requests.post(f'{settings.BASE_OAUTH2_PROVIDER_PUBLIC_URL}/token/', + data=data, + auth=auth) + print(response.content) + + auth_data = response.json() + if 'access_token' in auth_data: + auth_data['created_at'] = time.time() + cache.set('ads_access_token', auth_data, timeout=auth_data.get('expires_in') - 5) + + return auth_data + + +def log_request(request: Request): + print(request.headers['authorization']) + print( + f"Request event hook: {request.method} {request.url} {request.method} {request.headers} - Waiting for response") + + +def log_response(response): + request = response.request + print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}") + + +def get_client(): + access_token = login_as_client_credentials()['access_token'] + client = AuthenticatedClient(base_url="https://wallet.gooyal.com", token=access_token, + httpx_args={"event_hooks": {"request": [log_request], "response": [log_response]}}, + ) + return client + + +def deposit_to_user_wallet_submit(data): + class Tmp(): + def to_dict(self): + return data + + deposit_data = Tmp() + client = get_client() + response: ApplicationDeposit = wallet_api_application_deposit_create.sync(client=client, body=deposit_data) + print(response) + + return response + + +def deposit_to_user_wallet_verify(uuid): + client = get_client() + response: ApplicationDeposit = wallet_api_application_deposit_verify_retrieve.sync(uuid=uuid, client=client) + print(response) + + return response + + +def withdraw_from_user_wallet_submit(data): + class Tmp(): + def to_dict(self): + return data + + withdraw_data = Tmp() + client = get_client() + response: ApplicationWithdraw = wallet_api_application_withdraw_create.sync(client=client, body=withdraw_data) + print(response) + + return response + + +def withdraw_from_user_wallet_verify(uuid): + client = get_client() + response: ApplicationWithdraw = wallet_api_application_withdraw_verify_retrieve.sync(uuid=uuid, client=client) + print(response) + + return response + + +sample_data = { + "uuid": "3fa85f64-5717-4562-b3fc-2c963f66afb1", + "payee_id": "5d66d02e-6087-4b0a-bb0c-291d5c11755a", + "payee_type": 1, + "amount": 2000, + "details": "string", +}