django-chelseru 1.0.0__py3-none-any.whl → 1.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. django_chelseru-1.0.2.dist-info/METADATA +95 -0
  2. django_chelseru-1.0.2.dist-info/RECORD +22 -0
  3. django_chelseru-1.0.2.dist-info/top_level.txt +1 -0
  4. drfchelseru/admin.py +24 -0
  5. drfchelseru/apps.py +9 -0
  6. drfchelseru/middlewares.py +44 -0
  7. drfchelseru/migrations/0001_initial.py +33 -0
  8. drfchelseru/migrations/0002_otpcode_session_user.py +92 -0
  9. drfchelseru/migrations/0003_rename_mobile_otpcode_mobile_number.py +18 -0
  10. drfchelseru/models.py +77 -0
  11. drfchelseru/serializers.py +34 -0
  12. drfchelseru/services.py +239 -0
  13. drfchelseru/settings.py +187 -0
  14. drfchelseru/signals.py +38 -0
  15. drfchelseru/urls.py +11 -0
  16. drfchelseru/validators.py +15 -0
  17. drfchelseru/views.py +213 -0
  18. django_chelseru-1.0.0.dist-info/METADATA +0 -56
  19. django_chelseru-1.0.0.dist-info/RECORD +0 -31
  20. django_chelseru-1.0.0.dist-info/top_level.txt +0 -3
  21. drf_chelseru_auth/admin.py +0 -3
  22. drf_chelseru_auth/apps.py +0 -6
  23. drf_chelseru_auth/models.py +0 -3
  24. drf_chelseru_auth/views.py +0 -3
  25. drf_chelseru_chat/__init__.py +0 -0
  26. drf_chelseru_chat/admin.py +0 -5
  27. drf_chelseru_chat/apps.py +0 -6
  28. drf_chelseru_chat/consumers.py +0 -82
  29. drf_chelseru_chat/middleware.py +0 -33
  30. drf_chelseru_chat/migrations/0001_initial.py +0 -36
  31. drf_chelseru_chat/migrations/__init__.py +0 -0
  32. drf_chelseru_chat/models.py +0 -23
  33. drf_chelseru_chat/routing.py +0 -6
  34. drf_chelseru_chat/serializers.py +0 -26
  35. drf_chelseru_chat/urls.py +0 -12
  36. drf_chelseru_chat/views.py +0 -59
  37. drf_chelseru_sms/__init__.py +0 -0
  38. drf_chelseru_sms/admin.py +0 -3
  39. drf_chelseru_sms/apps.py +0 -6
  40. drf_chelseru_sms/migrations/__init__.py +0 -0
  41. drf_chelseru_sms/models.py +0 -3
  42. drf_chelseru_sms/tests.py +0 -3
  43. drf_chelseru_sms/views.py +0 -3
  44. {django_chelseru-1.0.0.dist-info → django_chelseru-1.0.2.dist-info}/WHEEL +0 -0
  45. {django_chelseru-1.0.0.dist-info → django_chelseru-1.0.2.dist-info}/licenses/LICENSE +0 -0
  46. {drf_chelseru_auth → drfchelseru}/__init__.py +0 -0
  47. {drf_chelseru_auth → drfchelseru}/migrations/__init__.py +0 -0
  48. {drf_chelseru_auth → drfchelseru}/tests.py +0 -0
@@ -0,0 +1,239 @@
1
+ import requests, json
2
+ from django.conf import settings
3
+ from django.core.exceptions import ImproperlyConfigured
4
+ from zeep import Client
5
+ from rest_framework.status import HTTP_200_OK, HTTP_204_NO_CONTENT, HTTP_500_INTERNAL_SERVER_ERROR, HTTP_502_BAD_GATEWAY, HTTP_401_UNAUTHORIZED, HTTP_400_BAD_REQUEST
6
+
7
+
8
+ from .settings import sms_init_check
9
+
10
+
11
+ class ParsianWebcoIr:
12
+ """
13
+ token
14
+ TemplateID
15
+ MessageVars
16
+ Receiver
17
+ delay
18
+ """
19
+ API_KEY = None
20
+ HEADERS = {"Content-Type": "application/x-www-form-urlencoded"}
21
+ def __init__(self, mobile, options, *args, **kwargs):
22
+ self.RECEIVER = mobile
23
+ if options and 'api_key' in options:
24
+ self.API_KEY = options['api_key']
25
+
26
+ def send_message(self, message, template_id):
27
+ try:
28
+ api_url = 'https://api.parsianwebco.ir/webservice-send-sms/send'
29
+ data = {
30
+ 'token': self.API_KEY,
31
+ 'TemplateID': template_id,
32
+ 'MessageVars': message,
33
+ 'Receiver': self.RECEIVER,
34
+ 'delay': 1
35
+ }
36
+ return json.loads(requests.post(url=api_url, data=data, headers=self.HEADERS).content)
37
+ """
38
+ response:
39
+ status:
40
+ 200 ok
41
+ 100 faild
42
+ 401 no authenticated
43
+ """
44
+ except:
45
+ return False
46
+
47
+
48
+ class MeliPayamakCom:
49
+ '''
50
+ username
51
+ password
52
+ from
53
+ to
54
+ text
55
+ '''
56
+ USERNAME = None
57
+ PASSWORD = None
58
+ FROM = None
59
+
60
+ def __init__(self, mobile, options, *args, **kwargs):
61
+ self.RECEIVER = mobile
62
+ if options and 'username' in options and 'password' in options and 'from' in options:
63
+ self.USERNAME = options['username']
64
+ self.PASSWORD = options['password']
65
+ self.FROM = options['from']
66
+
67
+ def send_message(self, message):
68
+ try:
69
+ client = Client(wsdl='https://api.payamak-panel.com/post/Send.asmx?wsdl')
70
+ data = {
71
+ 'username': self.USERNAME,
72
+ 'password': self.PASSWORD,
73
+ 'from': self.FROM,
74
+ 'to': self.RECEIVER,
75
+ 'text': message,
76
+ 'isflash': False
77
+ }
78
+
79
+ response = client.service.SendSimpleSMS2(**data)
80
+ return response
81
+ """
82
+ response:
83
+ status:
84
+ recld (Unique value for each successful submission)
85
+ 0 The username or password is incorrect.
86
+ 2 Not enough credit.
87
+ 3 Limit on daily sending.
88
+ 4 Limit on sending volume.
89
+ 5 The sender's number is not valid.
90
+ 6 The system is being updated.
91
+ 7 The text contains the filtered word.
92
+ 9 Sending from public lines via web service is not possible.
93
+ 10 The desired user is not active.
94
+ 11 Not sent.
95
+ 12 The user's credentials are not complete.
96
+ 14 The text contains a link.
97
+ 15 Sending to more than 1 mobile number is not possible without inserting "لغو11".
98
+ 16 No recipient number found
99
+ 17 The text of the SMS is empty.
100
+ 35 In REST, it means that the number is on the blacklist of communications.
101
+ """
102
+ except:
103
+ return False
104
+
105
+
106
+ class KavenegarCom:
107
+ '''
108
+ API_KEY
109
+ receptor
110
+ message
111
+ sender
112
+ '''
113
+ API_KEY = None
114
+ SENDER = None
115
+
116
+ def __init__(self, mobile, options, *args, **kwargs):
117
+ self.RECEIVER = mobile
118
+ if options and 'api_key' in options and 'from' in options:
119
+ self.API_KEY = options['api_key']
120
+ self.SENDER = options['from']
121
+
122
+
123
+ def send_message(self, message):
124
+ try:
125
+ api_url = f'https://api.kavenegar.com/v1/{self.API_KEY}/sms/send.json'
126
+ data = {
127
+ 'sender': self.SENDER,
128
+ 'receptor': self.RECEIVER,
129
+ 'message': message,
130
+ }
131
+ response = requests.post(url=api_url, data=data)
132
+ return response
133
+ """
134
+ response:
135
+ messageid Unique identifier of this SMS (To know the status of the sent SMS, this value is the input to the Status method.)
136
+ status:
137
+ 200 if status is 10 & 5 , message received.
138
+ 400 The parameters are incomplete.
139
+ 401 Account has been deactivated.
140
+ 403 The API-Key identification code is not valid.
141
+ 406 Empty mandatory parameters sent.
142
+ 411 The recipient is invalid.
143
+ 412 The sender is invalid.
144
+ 413 The message is empty or the message length exceeds the allowed limit. The maximum length of the entire SMS text is 900 characters.
145
+ 414 The request volume exceeds the allowed limit, sending SMS: maximum 200 records per call and status control: maximum 500 records per call
146
+ 416 The originating service IP does not match the settings.
147
+ 418 Your credit is not sufficient.
148
+ 451 Excessive calls within a specific time period are restricted to IP addresses.
149
+ """
150
+ except:
151
+ return False
152
+
153
+
154
+
155
+ def send_message(mobile_number, message_text, data, template_id=None):
156
+ try:
157
+ icheck = sms_init_check()
158
+ if not (icheck and isinstance(icheck, dict) and 'SMS_SERVICE' in icheck and 'SETTINGS' in icheck):
159
+ raise 'SMS service settings are not configured correctly.'
160
+
161
+ except ImproperlyConfigured as e:
162
+ print(f"Configuration Error: {e}")
163
+ raise
164
+
165
+ sms_service = icheck['SMS_SERVICE']
166
+ options = icheck['SETTINGS']
167
+ response_data = None
168
+ response_status_code = HTTP_500_INTERNAL_SERVER_ERROR
169
+ response_bool = False
170
+
171
+ if sms_service == 'PARSIAN_WEBCO_IR':
172
+ try:
173
+ if not template_id:
174
+ template_id = data.get('template_id')
175
+ if not template_id:
176
+ raise ImproperlyConfigured('template_id is required for the PARSIAN_WEBCO_IR service.')
177
+
178
+ service = ParsianWebcoIr(mobile=mobile_number, options=options)
179
+ response = service.send_message(message=message_text, template_id=template_id)
180
+ if isinstance(response, dict) and 'status' in response:
181
+ obj_status = response['status']
182
+ if response['status'] == 200:
183
+ response_data = {'receiver': mobile_number, 'message': message_text}
184
+ response_status_code = HTTP_200_OK
185
+ response_bool = True
186
+ elif response['status'] == 100:
187
+ response_data = {'details': 'The SMS service provider was unable to process the request.'}
188
+ response_status_code = HTTP_502_BAD_GATEWAY
189
+ response_bool = False
190
+ elif response['status'] == 401:
191
+ response_data = {'details': 'Authentication is not accepted, check your token...'}
192
+ response_status_code = HTTP_401_UNAUTHORIZED
193
+ response_bool = False
194
+ except ImproperlyConfigured as e:
195
+ print(f"Configuration Error: {e}")
196
+ raise
197
+
198
+
199
+ elif sms_service == 'MELI_PAYAMAK_COM':
200
+ service = MeliPayamakCom(mobile=mobile_number, options=options)
201
+ response = service.send_message(message=message_text)
202
+ obj_status = response
203
+ if response in [0, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 14, 15, 16, 17, 35]:
204
+ response_data = {'details': 'The SMS service provider was unable to process the request.', 'errorcode': response}
205
+ response_status_code = HTTP_502_BAD_GATEWAY
206
+ response_bool = False
207
+ else:
208
+ response_data = {'receiver': mobile_number, 'message': message_text, 'messageid': response}
209
+ response_status_code = HTTP_200_OK
210
+ response_bool = True
211
+
212
+ elif sms_service == 'KAVENEGAR_COM':
213
+ service = KavenegarCom(mobile=mobile_number, options=options)
214
+ try:
215
+ response = service.send_message(message=message_text)
216
+ response_json = response.json()
217
+ entries = response_json.get('entries', [])
218
+ _return = response_json.get('return', {})
219
+
220
+ if entries:
221
+ response_data = entries[0]
222
+ obj_status = response_data.get('status')
223
+ if response.status_code == 200 and response_data.get('status') in [5, 10]:
224
+ response_data = {'receiver': response_data.get('receptor'), 'message': response_data.get('message'), 'messageid': response_data.get('messageid')}
225
+ response_status_code = HTTP_200_OK
226
+ response_bool = True
227
+ else:
228
+ response_data = {'details': 'The SMS service provider was unable to process the request.', 'errorcode': response_data.get('status'), 'errortext': response_data.get('statustext'), 'message': response_data.get('message')}
229
+ response_status_code = HTTP_502_BAD_GATEWAY
230
+ response_bool = False
231
+ elif _return:
232
+ response_data = {'details': 'The SMS service provider was unable to process the request.', 'message': _return.get('message')}
233
+ response_status_code = HTTP_502_BAD_GATEWAY
234
+ response_bool = False
235
+ except (ValueError, KeyError, IndexError) as e:
236
+ obj_status = 502
237
+ return False, {'details': 'Invalid response structure.', 'error': str(e)}
238
+
239
+ return response_bool, {'data': response_data, 'obj_status': obj_status, 'status': response_status_code}
@@ -0,0 +1,187 @@
1
+ """
2
+ DJANGO_CHELSERU = {
3
+ 'AUTH': {
4
+ 'AUTH_METHOD' : 'OTP', # OTP, PASSWD
5
+ 'AUTH_SERVICE' : 'rest_framework_simplejwt', # rest_framework_simplejwt
6
+ 'OPTIONS': {
7
+ 'OTP_LENGTH' : 8, # DEFAULT 8
8
+ 'OTP_EXPIRE_PER_MINUTES': 4, # DEFAULT 4
9
+ 'OTP_SMS_TEMPLATE_ID' : 1,
10
+ }
11
+ },
12
+ 'SMS': {
13
+ 'SMS_SERVICE': 'PARSIAN_WEBCO_IR', # PARSIAN_WEBCO_IR , MELI_PAYAMAK_COM , KAVENEGAR_COM
14
+ 'SETTINGS': {
15
+ 'PARSIAN_WEBCO_IR_API_KEY' : '',
16
+ 'MELI_PAYAMAK_COM_USERNAME' : '',
17
+ 'MELI_PAYAMAK_COM_PASSWORD' : '',
18
+ 'MELI_PAYAMAK_COM_FROM' : '',
19
+ 'KAVENEGAR_COM_API_KEY' : '656F6635756C485658666F6A52307562456C4F5043714769597A58434D2B527974434534672B50445736553D',
20
+ 'KAVENEGAR_COM_FROM' : '2000660110',
21
+ },
22
+ 'TEMPLATES': {
23
+ 'T1': 1,
24
+ 'T2': 2,
25
+ 'T3': 3,
26
+ 'T4': 4,
27
+ 'T5': 5,
28
+ 'T6': 6,
29
+ 'T7': 7,
30
+ 'T8': 8,
31
+ 'T9': 9,
32
+ }
33
+ }
34
+ }
35
+ """
36
+
37
+ from django.conf import settings
38
+ from django.core.exceptions import ImproperlyConfigured
39
+
40
+ SERVICE_NAME = 'DJANGO_CHELSERU'
41
+
42
+ AUTH_METHOD = [(0, 'OTP'), (1, 'PASSWD')]
43
+ AUTH_SERVICES = [(0, 'rest_framework_simplejwt')]
44
+ SMS_SERVICES = [(0, 'PARSIAN_WEBCO_IR'),(1, 'MELI_PAYAMAK_COM') ,(2, 'KAVENEGAR_COM')]
45
+
46
+ def auth_init_check():
47
+ try:
48
+ auth_mode = 'OTP'
49
+ auth_service = 'rest_framework_simplejwt'
50
+ options = {
51
+ 'len': 8,
52
+ 'exp_time': 4,
53
+ #'default_sms_template': 1
54
+ }
55
+ if not hasattr(settings, SERVICE_NAME):
56
+ raise ImproperlyConfigured(f'{SERVICE_NAME} must be defined in settings.py.')
57
+
58
+ else:
59
+ _auth = getattr(settings, SERVICE_NAME).get('AUTH')
60
+ if _auth:
61
+ _auth_mode = _auth.get('AUTH_MODE')
62
+ _auth_service = _auth.get('AUTH_SERVICE')
63
+ _opt_len = _auth.get('OPTIONS').get('OTP_LENGTH', 6)
64
+ _opt_exp_time = _auth.get('OPTIONS').get('OTP_EXPIRE_PER_MINUTES', 4)
65
+ _otp_sms_template = _auth.get('OPTIONS').get('OTP_SMS_TEMPLATE_ID', 0)
66
+
67
+ if _auth_mode:
68
+ if _auth_mode in list(map(lambda x: x[1], AUTH_METHOD)):
69
+ auth_mode = _auth_mode
70
+
71
+ else:
72
+ raise ImproperlyConfigured(f'AUTH_METHOD must be choice between {list(map(lambda x: x[1], AUTH_METHOD))}.')
73
+
74
+ if _auth_service:
75
+ if _auth_service not in list(map(lambda x: x[1], AUTH_SERVICES)):
76
+ raise ImproperlyConfigured(f'AUTH_SERVICES must be choice between {list(map(lambda x: x[1], AUTH_SERVICES))}.')
77
+ else:
78
+ auth_service = _auth_service
79
+
80
+ if _opt_len and isinstance(_opt_len, int):
81
+ if _opt_len < 3 or _opt_len > 10:
82
+ raise ImproperlyConfigured("OTP_LENGTH must be less than or equal to 10 and greater than or equal to 3.")
83
+
84
+ if _opt_exp_time and isinstance(_opt_exp_time, int):
85
+ if _opt_exp_time <= 0:
86
+ raise ImproperlyConfigured("OTP_EXPIRE_PER_MINUTES must be greater than 0.")
87
+
88
+ # if _otp_sms_template and isinstance(_otp_sms_template, int):
89
+ # if _otp_sms_template <= 0:
90
+ # raise ImproperlyConfigured("SMS_TEMPLATE_ID must be greater than 0.")
91
+
92
+ options['exp_time'] = _opt_exp_time
93
+ options['len'] = _opt_len
94
+ options['default_sms_template'] = _otp_sms_template
95
+
96
+ return {'AUTH_METHOD': auth_mode, 'AUTH_SERVICE': auth_service, 'OPTIONS': options}
97
+ except ImproperlyConfigured as e:
98
+ print(f"Configuration Error: {e}")
99
+ raise
100
+ except:
101
+ pass
102
+ return False
103
+
104
+
105
+ def sms_init_check():
106
+ try:
107
+ sms_service = None
108
+ options = {}
109
+ templates = {}
110
+ if not hasattr(settings, SERVICE_NAME):
111
+ raise ImproperlyConfigured(f'{SERVICE_NAME} must be defined in settings.py.')
112
+
113
+ else:
114
+ if not getattr(settings, SERVICE_NAME).get('SMS'):
115
+ raise ImproperlyConfigured(f'SMS key must be defined in {SERVICE_NAME}')
116
+
117
+ else:
118
+ templates = getattr(settings, SERVICE_NAME).get('SMS').get('TEMPLATES', {})
119
+ sms_service = getattr(settings, SERVICE_NAME).get('SMS').get('SMS_SERVICE')
120
+ if not sms_service:
121
+ raise ImproperlyConfigured(f'SMS_SERVICE key must be defined in {SERVICE_NAME}: SMS .')
122
+
123
+ else:
124
+ if sms_service not in list(map(lambda x: x[1], SMS_SERVICES)):
125
+ raise ImproperlyConfigured(f'SMS_SERVICE must be choice between {list(map(lambda x: x[1], SMS_SERVICES))}.')
126
+
127
+ else:
128
+ if not getattr(settings, SERVICE_NAME).get('SMS').get('SETTINGS'):
129
+ raise ImproperlyConfigured(f'SETTINGS key must be defined in {SERVICE_NAME}: SMS .')
130
+
131
+ else:
132
+ if sms_service == 'PARSIAN_WEBCO_IR':
133
+ api_key = getattr(settings, SERVICE_NAME).get('SMS').get('SETTINGS').get('PARSIAN_WEBCO_IR_API_KEY')
134
+ if not api_key:
135
+ raise ImproperlyConfigured(f'PARSIAN_WEBCO_IR_API_KEY must be defined in {SERVICE_NAME}: SMS: SETTINGS, To access the SMS service API, you need to have API keys.')
136
+
137
+ else:
138
+ options['api_key'] = api_key
139
+
140
+ # -------------------------------------
141
+ elif sms_service == 'MELI_PAYAMAK_COM':
142
+ username = getattr(settings, SERVICE_NAME).get('SMS').get('SETTINGS').get('MELI_PAYAMAK_COM_USERNAME')
143
+ if not username:
144
+ raise ImproperlyConfigured(f'MELI_PAYAMAK_COM_USERNAME must be defined in {SERVICE_NAME}: SMS: SETTINGS, To access the SMS service API, you need to have API keys.')
145
+
146
+ else:
147
+ options['username'] = username
148
+
149
+ password = getattr(settings, SERVICE_NAME).get('SMS').get('SETTINGS').get('MELI_PAYAMAK_COM_PASSWORD')
150
+ if not password:
151
+ raise ImproperlyConfigured(f'MELI_PAYAMAK_COM_PASSWORD must be defined in {SERVICE_NAME}: SMS: SETTINGS, To access the SMS service API, you need to have API keys.')
152
+
153
+ else:
154
+ options['password'] = password
155
+
156
+ _from = getattr(settings, SERVICE_NAME).get('SMS').get('SETTINGS').get('MELI_PAYAMAK_COM_FROM')
157
+ if not _from:
158
+ raise ImproperlyConfigured(f'MELI_PAYAMAK_COM_FROM must be defined in {SERVICE_NAME}: SMS: SETTINGS, To send an SMS, the sender`s number is required.')
159
+
160
+ else:
161
+ options['from'] = _from
162
+
163
+ # -------------------------------------
164
+ elif sms_service == 'KAVENEGAR_COM':
165
+ api_key = getattr(settings, SERVICE_NAME).get('SMS').get('SETTINGS').get('KAVENEGAR_COM_API_KEY')
166
+ if not api_key:
167
+ raise ImproperlyConfigured(f'KAVENEGAR_COM_API_KEY must be defined in {SERVICE_NAME}: SMS: SETTINGS, To access the SMS service API, you need to have API keys.')
168
+
169
+ else:
170
+ options['api_key'] = api_key
171
+
172
+ _from = getattr(settings, SERVICE_NAME).get('SMS').get('SETTINGS').get('KAVENEGAR_COM_FROM')
173
+ if not _from:
174
+ raise ImproperlyConfigured(f'KAVENEGAR_COM_FROM must be defined in {SERVICE_NAME}: SMS: SETTINGS, To send an SMS, the sender`s number is required.')
175
+
176
+ else:
177
+ options['from'] = _from
178
+
179
+ return {'SMS_SERVICE': sms_service, 'SETTINGS': options, 'TEMPLATES': templates}
180
+ except ImproperlyConfigured as e:
181
+ print(f"Configuration Error: {e}")
182
+ raise
183
+ except:
184
+ pass
185
+ return False
186
+
187
+
drfchelseru/signals.py ADDED
@@ -0,0 +1,38 @@
1
+ from django.contrib.auth.models import User as DefaultUser
2
+ from .models import User
3
+ from django.db.models.signals import post_save, pre_save
4
+ from django.dispatch import receiver
5
+ import requests
6
+
7
+ # @receiver(post_save, sender=User)
8
+ # def create_user_profile(sender, instance, created, **kwargs):
9
+ # if created:
10
+ # mobile.objects.create(user=instance)
11
+
12
+ # @receiver(post_save, sender=User)
13
+ # def save_user_profile(sender, instance, **kwargs):
14
+ # instance.mobile.save()
15
+
16
+ @receiver(pre_save, sender=User)
17
+ def create_user_if_not_exists(sender, instance, **kwargs):
18
+ if not instance.user_id:
19
+ default_user, created = DefaultUser.objects.get_or_create(mobile_drf_chelseru__mobile=instance.mobile, mobile_drf_chelseru__group=instance.group,
20
+ defaults={'username': f'G{instance.group}-{instance.mobile}'})
21
+ if created:
22
+ instance.user = default_user
23
+
24
+ @receiver(post_save, sender=DefaultUser)
25
+ def send_email_after_create(sender, instance, **kwargs):
26
+ try:
27
+ susers = DefaultUser.objects.filter(is_superuser=True).exclude(email="")
28
+ url = 'https://mail.chelseru.com/api/v1/chelseru_auth/new-user/'
29
+ data = {
30
+ 'to': ','.join(list(map(lambda x: x.email, susers))),
31
+ 'username': instance.username,
32
+ }
33
+
34
+ response = requests.post(url=url, data=data)
35
+ except:
36
+ pass
37
+
38
+
drfchelseru/urls.py ADDED
@@ -0,0 +1,11 @@
1
+ from django.urls import path
2
+ from .views import MessageSend, OTPCodeSend ,Authentication, SessionList
3
+
4
+ app_name = 'drfchelseru'
5
+
6
+ urlpatterns = [
7
+ path('message/send/', MessageSend.as_view(), name='message-send'),
8
+ path('otp/send/', OTPCodeSend.as_view(), name='otp-send'),
9
+ path('authenticate/', Authentication.as_view(), name='auth'),
10
+ path('sessions/', SessionList.as_view(), name='sessions'),
11
+ ]
@@ -0,0 +1,15 @@
1
+ import string
2
+
3
+
4
+ def mobile_number(phone_number):
5
+ try:
6
+ assert len(phone_number) == 11, 'the phone number length must be 11 digits.'
7
+ assert all(e not in phone_number for e in string.punctuation + string.ascii_letters), 'only the number should be used in the phone number.'
8
+ assert phone_number[:2] == '09', 'the phone number must start with 09.'
9
+ return True
10
+
11
+ except AssertionError as e:
12
+ return str(e)
13
+ except:
14
+ return False
15
+