Spaces:
Sleeping
Sleeping
Upload 91 files
Browse files- .gitattributes +12 -0
- .gitignore +39 -0
- 1.jpg +3 -0
- 2.jpg +0 -0
- Dockerfile +6 -6
- api/bestSellers.json +236 -0
- api/trendingProducts.json +102 -0
- api/urls.py +1 -0
- api/views.py +61 -36
- authentication/migrations/__pycache__/0001_initial.cpython-311.pyc +0 -0
- authentication/migrations/__pycache__/0002_alter_userdata_coupons_alter_userdata_otp.cpython-311.pyc +0 -0
- authentication/migrations/__pycache__/0003_alter_coupon_expirydate.cpython-311.pyc +0 -0
- authentication/migrations/__pycache__/0004_coupon_discription.cpython-311.pyc +0 -0
- authentication/migrations/__pycache__/0005_userdata_refcode.cpython-311.pyc +0 -0
- authentication/migrations/__pycache__/0006_userdata_activatedcoupons.cpython-311.pyc +0 -0
- authentication/migrations/__pycache__/0007_userdata_revelid.cpython-311.pyc +0 -0
- authentication/migrations/__pycache__/0008_alter_userdata_pincode.cpython-311.pyc +0 -0
- authentication/migrations/__pycache__/__init__.cpython-311.pyc +0 -0
- authentication/views copy.py +441 -0
- authentication/views.py +87 -23
- barcode.png +0 -0
- dataScript.js +161 -0
- db.sqlite3 +0 -0
- demo.svg +41 -0
- locations.json +0 -0
- oneOone/settings.py +15 -11
- oneOone/urls.py +4 -3
- requirements.txt +0 -0
- revelAPI.py +12 -0
- rewardsRevelAPI.py +80 -0
- static/home/1.jpg +3 -0
- static/home/1.png +3 -0
- static/home/2.jpg +3 -0
- static/home/2.png +3 -0
- static/home/3.jpg +3 -0
- static/home/3.png +3 -0
- static/home/4.jpg +3 -0
- static/home/4.png +3 -0
- static/home/5.jpg +3 -0
- static/home/5.png +3 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,15 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
1.jpg filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
db.sqlite3 filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
static/home/1.jpg filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
static/home/1.png filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
static/home/2.jpg filter=lfs diff=lfs merge=lfs -text
|
| 41 |
+
static/home/2.png filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
static/home/3.jpg filter=lfs diff=lfs merge=lfs -text
|
| 43 |
+
static/home/3.png filter=lfs diff=lfs merge=lfs -text
|
| 44 |
+
static/home/4.jpg filter=lfs diff=lfs merge=lfs -text
|
| 45 |
+
static/home/4.png filter=lfs diff=lfs merge=lfs -text
|
| 46 |
+
static/home/5.jpg filter=lfs diff=lfs merge=lfs -text
|
| 47 |
+
static/home/5.png filter=lfs diff=lfs merge=lfs -text
|
.gitignore
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.venv/*
|
| 2 |
+
|
| 3 |
+
# dependencies
|
| 4 |
+
frontend/node_modules/
|
| 5 |
+
|
| 6 |
+
# Expo
|
| 7 |
+
frontend/.expo/
|
| 8 |
+
frontend/dist/
|
| 9 |
+
frontend/web-build/
|
| 10 |
+
|
| 11 |
+
# Native
|
| 12 |
+
frontend/*.orig.*
|
| 13 |
+
frontend/*.jks
|
| 14 |
+
frontend/*.p8
|
| 15 |
+
frontend/*.p12
|
| 16 |
+
frontend/*.key
|
| 17 |
+
frontend/*.mobileprovision
|
| 18 |
+
|
| 19 |
+
# Metro
|
| 20 |
+
frontend/.metro-health-check*
|
| 21 |
+
|
| 22 |
+
# debug
|
| 23 |
+
frontend/npm-debug.*
|
| 24 |
+
frontend/yarn-debug.*
|
| 25 |
+
frontend/yarn-error.*
|
| 26 |
+
|
| 27 |
+
# macOS
|
| 28 |
+
frontend/.DS_Store
|
| 29 |
+
frontend/*.pem
|
| 30 |
+
|
| 31 |
+
# local env files
|
| 32 |
+
frontend/.env*.local
|
| 33 |
+
|
| 34 |
+
# typescript
|
| 35 |
+
frontend/*.tsbuildinfo
|
| 36 |
+
db.sqlite3
|
| 37 |
+
data.json
|
| 38 |
+
frontend/101.zip
|
| 39 |
+
frontend/.env
|
1.jpg
ADDED
|
Git LFS Details
|
2.jpg
ADDED
|
Dockerfile
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
-
FROM python:3
|
| 2 |
-
WORKDIR /usr/src/app
|
| 3 |
-
COPY requirements.txt ./
|
| 4 |
-
RUN pip install -r requirements.txt
|
| 5 |
-
COPY . .
|
| 6 |
-
EXPOSE 7860
|
| 7 |
CMD ["python","./manage.py","runserver","0.0.0.0:7860"]
|
|
|
|
| 1 |
+
FROM python:3
|
| 2 |
+
WORKDIR /usr/src/app
|
| 3 |
+
COPY requirements.txt ./
|
| 4 |
+
RUN pip install -r requirements.txt
|
| 5 |
+
COPY . .
|
| 6 |
+
EXPOSE 7860
|
| 7 |
CMD ["python","./manage.py","runserver","0.0.0.0:7860"]
|
api/bestSellers.json
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"name": "CHOCCART - GROCERY - CANDY - DUBAI CHOCOLATE - 37GM/PK - 24PK/BX - KUNAFA & PISTACHIO",
|
| 4 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/CHOCCART-GROCERY-CANDY-DUBAI-CHOCOLATE-37GMPK-24PKBX-KUNAFA-PISTACHIO17588391842102025-09-25-22-26-231KrlL.png",
|
| 5 |
+
"link": "https://101smokeshop.com/",
|
| 6 |
+
"price": "40.49"
|
| 7 |
+
},
|
| 8 |
+
{
|
| 9 |
+
"name": "MIRCATA - GROCERY - CANDY - DUBAI CHOCOLATE - 20GM/PK - 48PK/BX - ASSORTED FLAVORS",
|
| 10 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/MIRCATA-GROCERY-CANDY-DUBAI-CHOCOLATE-20GMPK-48PKBX-ASSORTED-FLAVORS17588389251102025-09-25-22-22-04wvWZa.png",
|
| 11 |
+
"link": "https://101smokeshop.com/",
|
| 12 |
+
"price": "49.99"
|
| 13 |
+
},
|
| 14 |
+
{
|
| 15 |
+
"name": "MIRCATA - GROCERY - CANDY - DUBAI CHOCOLATE - 20GM/PK - 36PK/BX - PISTACHIO KUNAFA",
|
| 16 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/MIRCATA-GROCERY-CANDY-DUBAI-CHOCOLATE-20GMPK-36PKBX-PISTACHIO-KUNAFA17588390137622025-09-25-22-23-33J3BX0.png",
|
| 17 |
+
"link": "https://101smokeshop.com/",
|
| 18 |
+
"price": "37.49"
|
| 19 |
+
},
|
| 20 |
+
{
|
| 21 |
+
"name": "AL SUWISSRIA - GROCERY - CANDY - DUBAI CHOCOLATE - 200GM/PK - 6PK/BX",
|
| 22 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/AL-SUWISSRIA-GROCERY-CANDY-DUBAI-CHOCOLATE-200GMPK-6PKBX17588397315172025-09-25-22-35-31176DM.png",
|
| 23 |
+
"link": "https://101smokeshop.com/",
|
| 24 |
+
"price": "48.49"
|
| 25 |
+
},
|
| 26 |
+
{
|
| 27 |
+
"name": "BUBBLE BITEZ - GROCERY - GUM - 2.47OZ.PK - 12PK/BX - GUMBALL",
|
| 28 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/BUBBLE-BITEZ-GROCERY-GUM-2-47OZ-PK-12PKBX-GUMBALL17589135406132025-09-26-19-05-40eKvG5.png",
|
| 29 |
+
"link": "https://101smokeshop.com/",
|
| 30 |
+
"price": "17.99"
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"name": "LOLLI CHOMPERS - GROCERY - TOY CANDY - 0.39OZ/CT - 16CT/BX - DRAGON - STRAWBERRY",
|
| 34 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/LOLLI-CHOMPERS-GROCERY-TOY-CANDY-0-39OZCT-16CTBX-DRAGON-STRAWBERRY17589134591832025-09-26-19-04-18etHa6.png",
|
| 35 |
+
"link": "https://101smokeshop.com/",
|
| 36 |
+
"price": "47.49"
|
| 37 |
+
},
|
| 38 |
+
{
|
| 39 |
+
"name": "PIP SQUEAKS - GROCERY - TOY CANDY - 0.4OZ/CT - 12CT/BX - SURPRISE PETS & CANDY",
|
| 40 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/PIP-SQUEAKS-GROCERY-TOY-CANDY-0-4OZCT-12CTBX-SURPRISE-PETS-CANDY17589136282242025-09-26-19-07-07b88nW.png",
|
| 41 |
+
"link": "https://101smokeshop.com/",
|
| 42 |
+
"price": "25.49"
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
"name": "WHIRLY KATS - GROCERY - TOY CANDY - 0.35OZ/CT - 16CT/BX - LIGHT UP TOY & FRUITY",
|
| 46 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/WHIRLY-KATS-GROCERY-TOY-CANDY-0-35OZCT-16CTBX-LIGHT-UP-TOY-FRUITY17589136900772025-09-26-19-08-09o4CA7.png",
|
| 47 |
+
"link": "https://101smokeshop.com/",
|
| 48 |
+
"price": "45.49"
|
| 49 |
+
},
|
| 50 |
+
{
|
| 51 |
+
"name": "TWIRLY FINS - GROCERY - TOY CANDY - 0.35OZ/CT - 16CT/BX - DOLPHINS",
|
| 52 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/TWIRLY-FINS-GROCERY-TOY-CANDY-0-35OZCT-16CTBX-DOLPHINS17589141164852025-09-26-19-15-15VMRb9.png",
|
| 53 |
+
"link": "https://101smokeshop.com/",
|
| 54 |
+
"price": "45.49"
|
| 55 |
+
},
|
| 56 |
+
{
|
| 57 |
+
"name": "AIRHEADS - XTREMES - GROCERY - CANDY - HC - 2.80OZ/CT - SOURFULS - RAINBOW BERRY",
|
| 58 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/AIRHEADS-XTREMES-GROCERY-CANDY-HC-2-80OZCT-SOURFULS-RAINBOW-BERRY17585666200542025-09-22-18-43-41Ea9JM.png",
|
| 59 |
+
"link": "https://101smokeshop.com/",
|
| 60 |
+
"price": "1.25"
|
| 61 |
+
},
|
| 62 |
+
{
|
| 63 |
+
"name": "WARHEADS - GROCERY - CANDY - CUBES - 3.5OZ/PK - 1PK - SOUR BERRY MIX",
|
| 64 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/WARHEADS-GROCERY-CANDY-CUBES-3-5OZPK-1PK-SOUR-BERRY-MIX17576979134352025-09-12-17-25-12cvGt6.jpg",
|
| 65 |
+
"link": "https://101smokeshop.com/",
|
| 66 |
+
"price": "1.25"
|
| 67 |
+
},
|
| 68 |
+
{
|
| 69 |
+
"name": "KIDSMANIA - GROCERY - TOY CANDY - 1.52OZ/CT - 12CT/BX - SWEET BANDIT - STELLAR STORM STICK",
|
| 70 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/KIDSMANIA-GROCERY-TOY-CANDY-1-52OZCT-12CTBX-SWEET-BANDIT-STELLAR-STORM-STICK17573687223052025-09-08-21-58-42DXwMF.jpg",
|
| 71 |
+
"link": "https://101smokeshop.com/",
|
| 72 |
+
"price": "13.99"
|
| 73 |
+
},
|
| 74 |
+
{
|
| 75 |
+
"name": "KIDSMANIA - GROCERY - TOY CANDY - 2.47OZ/CT - 12CT/BX - SWEET BANDIT - DIZZYDAZZLE DROPS",
|
| 76 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/KIDSMANIA-GROCERY-TOY-CANDY-2-47OZCT-12CTBX-SWEET-BANDIT-DIZZYDAZZLE-DROPS17573682356342025-09-08-21-50-359yrkG.jpg",
|
| 77 |
+
"link": "https://101smokeshop.com/",
|
| 78 |
+
"price": "13.99"
|
| 79 |
+
},
|
| 80 |
+
{
|
| 81 |
+
"name": "CADBURY - DAIRY MILK - GROCERY - CANDY - SS - 3.5OZ/PK - 14PK/BX",
|
| 82 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/CADBURY-DAIRY-MILK-GROCERY-CANDY-SS-3-5OZPK-14PKBX17567565356712025-09-01-19-55-36uS2fg.jpg",
|
| 83 |
+
"link": "https://101smokeshop.com/",
|
| 84 |
+
"price": "40.99"
|
| 85 |
+
},
|
| 86 |
+
{
|
| 87 |
+
"name": "COOLIOH - GROCERY - CANDY - FREEZE DRIED - 2.4OZ/PK - 6PK/BX - DUBAI CHOCOLATE FIX",
|
| 88 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/COOLIOH-GROCERY-CANDY-FREEZE-DRIED-2-4OZPK-6PKBX-DUBAI-CHOCOLATE-FIX17552772947842025-08-15-17-01-35VyOab.jpg",
|
| 89 |
+
"link": "https://101smokeshop.com/",
|
| 90 |
+
"price": "26.99"
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"name": "SOUR PATCH - KIDS - GROCERY - CANDY - 0.19OZ/CT - 50CT/PK - MONSTER HEADS",
|
| 94 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/SOUR-PATCH-KIDS-GROCERY-CANDY-0-19OZCT-50CTPK-MONSTER-HEADS17546689881522025-08-08-16-03-07YiTQ3.jpg",
|
| 95 |
+
"link": "https://101smokeshop.com/",
|
| 96 |
+
"price": "2.99"
|
| 97 |
+
},
|
| 98 |
+
{
|
| 99 |
+
"name": "OCEAN - GROCERY - CANDY - DUBAI CHOCOLATE - 6PK/BX",
|
| 100 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/OCEAN-GROCERY-CANDY-6PKBX-DUBAI-CHOCOLATE17538965623122025-07-30-17-29-21INSRv.jpg",
|
| 101 |
+
"link": "https://101smokeshop.com/",
|
| 102 |
+
"price": "46.99"
|
| 103 |
+
},
|
| 104 |
+
{
|
| 105 |
+
"name": "MOUNDS - GROCERY - CANDY - 1.75OZ/CT - 24CT/BX - REGULAR",
|
| 106 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/MOUNDS-GROCERY-CANDY-1-75OZCT-24CTBX-REGULAR17532207309122025-07-22-21-45-32inCY5.jpg",
|
| 107 |
+
"link": "https://101smokeshop.com/",
|
| 108 |
+
"price": "22.99"
|
| 109 |
+
},
|
| 110 |
+
{
|
| 111 |
+
"name": "TIC TAC - GROCERY - CANDY - 1.7OZ/CT - 12CT/BX",
|
| 112 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/TIC-TAC-GROCERY-CANDY-1-7OZCT-12CTBX17532205879942025-07-22-21-43-09MrrLt.jpg",
|
| 113 |
+
"link": "https://101smokeshop.com/",
|
| 114 |
+
"price": "17.49"
|
| 115 |
+
},
|
| 116 |
+
{
|
| 117 |
+
"name": "RICKY JOY - GROCERY - CANDY - 3.9OZ/CT - 3CT/DISP - CRAZY LEGS - MARSHMALLOW TWIST",
|
| 118 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/RICKY-JOY-GROCERY-CANDY-3-9OZCT-3CTDISP-CRAZY-LEGS-MARSHMALLOW-TWIST17520835536452025-07-09-17-52-33iRAgv.jpg",
|
| 119 |
+
"link": "https://101smokeshop.com/",
|
| 120 |
+
"price": "11.49"
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"name": "AMOS - PEELERZ - GROCERY - GUMMY - CANDY - HC - 6OZ/PK - 1PK",
|
| 124 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/AMOS-PEELERZ-GROCERY-GUMMY-CANDY-HC-6OZPK-1PK17520897021172025-07-09-19-35-02roxbF.jpg",
|
| 125 |
+
"link": "https://101smokeshop.com/",
|
| 126 |
+
"price": "3.49"
|
| 127 |
+
},
|
| 128 |
+
{
|
| 129 |
+
"name": "DON VICTOR - GROCERY - MEXICAN HONEY - 8OZ/JR - WITH COMB",
|
| 130 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/DON-VICTOR-GROCERY-MEXICAN-HONEY-8OZJR-WITH-COMB17513230164702025-06-30-22-36-56mXo4p.jpg",
|
| 131 |
+
"link": "https://101smokeshop.com/",
|
| 132 |
+
"price": "5.99"
|
| 133 |
+
},
|
| 134 |
+
{
|
| 135 |
+
"name": "MCCROMICK - GROCERY - MEXICAN MAYONESA - 13.75OZ/JR - WITH LEMON JUICE",
|
| 136 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/MCCROMICK-GROCERY-MEXICAN-MAYONESA-13-75OZJR-WITH-LEMON-JUICE17513897183852025-07-01-17-08-37M8NoD.jpg",
|
| 137 |
+
"link": "https://101smokeshop.com/",
|
| 138 |
+
"price": "5.49"
|
| 139 |
+
},
|
| 140 |
+
{
|
| 141 |
+
"name": "LA LUPITA - GROCERY - MEXICAN CANDY - MICHELADA - 32OZ/JR",
|
| 142 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/LA-LUPITA-GROCERY-MEXICAN-CANDY-MICHELADA-32OZJR17514104506202025-07-01-22-54-108x1ia.jpg",
|
| 143 |
+
"link": "https://101smokeshop.com/",
|
| 144 |
+
"price": "2.99"
|
| 145 |
+
},
|
| 146 |
+
{
|
| 147 |
+
"name": "RICOLINE - GROCERY - MEXICAN CANDY - MINI PALETA PAYASO - 0.88OZ/CT - 15CT/BX - MARSHMALLOW WITH CHOCOLATE",
|
| 148 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/RICOLINE-GROCERY-MEXICAN-CANDY-MINI-PALETA-PAYASO-0-88OZCT-15CTBX-MARSHMALLOW-WITH-CHOCOLATE17513856249692025-07-01-16-00-25eh0BD.jpg",
|
| 149 |
+
"link": "https://101smokeshop.com/",
|
| 150 |
+
"price": "7.49"
|
| 151 |
+
},
|
| 152 |
+
{
|
| 153 |
+
"name": "SQUEEZY SQUIRT POP - GROCERY - TOY CANDY - 12.7OZ/CT - 12CT/BX - LOLLIPOP",
|
| 154 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/SQUEEZY-SQUIRT-POP-GROCERY-TOY-CANDY-12-7OZCT-12CTBX-LOLLIPOP17509652301422025-06-26-19-13-51LHKnm.jpg",
|
| 155 |
+
"link": "https://101smokeshop.com/",
|
| 156 |
+
"price": "12.75"
|
| 157 |
+
},
|
| 158 |
+
{
|
| 159 |
+
"name": "CRAZY CHOCO - GROCERY - CANDY - DUBAI CHOCOLATE - 200GM/PK - 1PK",
|
| 160 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/DUBAI-CHOCOLATE-GROCERY-CANDY-200GMCT-1CTBX17514757038872025-07-02-17-01-445iowK.jpg",
|
| 161 |
+
"link": "https://101smokeshop.com/",
|
| 162 |
+
"price": "15.99"
|
| 163 |
+
},
|
| 164 |
+
{
|
| 165 |
+
"name": "PATISLOVE - GROCERY - CANDY - DUBAI CHOCOLATE - 200GM/PK - 10PK/BX",
|
| 166 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/PATISLOVE-GROCERY-CANDY-200GMCT-10CTBX-DUBAI-CHOCOLATE17508014818152025-06-24-21-44-42bZww4.jpg",
|
| 167 |
+
"link": "https://101smokeshop.com/",
|
| 168 |
+
"price": "143.25"
|
| 169 |
+
},
|
| 170 |
+
{
|
| 171 |
+
"name": "MARDINNI - GROCERY - CANDY - DUBAI CHOCOLATE - 200GM/PK - 6PK/BX",
|
| 172 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/MARDINNI-GROCERY-CANDY-200GMCT-6CTBX-DUBAI-CHOCOLATE17508014407932025-06-24-21-44-01lQkBo.jpg",
|
| 173 |
+
"link": "https://101smokeshop.com/",
|
| 174 |
+
"price": "82.49"
|
| 175 |
+
},
|
| 176 |
+
{
|
| 177 |
+
"name": "DULCES IDEAS - GROCERY - CANDY - 50CT/BX - PALETAS DE BOMBON - ARTISAN MARSHMALLOW",
|
| 178 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/DULCES-IDEAS-GROCERY-CANDY-50CTBX-PALETAS-DE-BOMBON-ARTISAN-MARSHMALLOW17520723192582025-07-09-14-45-18BxSkD.jpg",
|
| 179 |
+
"link": "https://101smokeshop.com/",
|
| 180 |
+
"price": "199.99"
|
| 181 |
+
},
|
| 182 |
+
{
|
| 183 |
+
"name": "BOBBO - GROCERY - TOY CANDY - 24CT/BX - HOTDOG",
|
| 184 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/BOBBO-GROCERY-TOY-CANDY-24CTBX-HOTDOG17508701090762025-06-25-16-48-29qEqnU.jpg",
|
| 185 |
+
"link": "https://101smokeshop.com/",
|
| 186 |
+
"price": "13.99"
|
| 187 |
+
},
|
| 188 |
+
{
|
| 189 |
+
"name": "TAI FUN - GROCERY - TOY CANDY - 0.71OZ/CT - 12CT/BX - FRUITY MIX",
|
| 190 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/TAI-FUN-GROCERY-TOY-CANDY-0-71OZCT-12CTBX-FRUITY-MIX17502655374142025-06-18-16-52-17d0MFu.jpg",
|
| 191 |
+
"link": "https://101smokeshop.com/",
|
| 192 |
+
"price": "24.99"
|
| 193 |
+
},
|
| 194 |
+
{
|
| 195 |
+
"name": "SNAK CLUB - GROCERY - CANDY - HANGING - 1PK",
|
| 196 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/SNAK-CLUB-GROCERY-CANDY-HANGING-1PK17472530108732025-05-14-20-03-29kCjKd.jpg",
|
| 197 |
+
"link": "https://101smokeshop.com/",
|
| 198 |
+
"price": "2.59"
|
| 199 |
+
},
|
| 200 |
+
{
|
| 201 |
+
"name": "COCO CANDY - GROCERY - TOY CANDY - 20CT/BX - SWEET N'SIP - LOLLIPOP",
|
| 202 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/coco-candy-grocery-toy-candy-20ct-bx-sweet-n-sip-lollipop17462137504272025-05-02-19-22-31wXyjp.jpg",
|
| 203 |
+
"link": "https://101smokeshop.com/",
|
| 204 |
+
"price": "26.49"
|
| 205 |
+
},
|
| 206 |
+
{
|
| 207 |
+
"name": "RICKY JOY - GROCERY - CANDY - COTTON CANDY - 3OZ/PK - 1PK - CHILI CHAMOY",
|
| 208 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/ricky-joy-grocery-candy-cotton-candy-3oz-pk-1pk-chili-chamoy17462190503352025-05-02-20-50-50Ju01C.jpg",
|
| 209 |
+
"link": "https://101smokeshop.com/",
|
| 210 |
+
"price": "2.49"
|
| 211 |
+
},
|
| 212 |
+
{
|
| 213 |
+
"name": "M&M - GROCERY - CANDY - 1.74OZ/PK - 48PK/BX - PEANUT - CHOCOLATE CANDIES",
|
| 214 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/M-M-GROCERY-CANDY-1-74OZPK-48PKBX-PEANUT-CHOCOLATE-CANDIES17458648601572025-04-28-18-27-39nSbAq.jpg",
|
| 215 |
+
"link": "https://101smokeshop.com/",
|
| 216 |
+
"price": "55.99"
|
| 217 |
+
},
|
| 218 |
+
{
|
| 219 |
+
"name": "JOLLY RANCHER - GROCERY - CANDY - 6.5OZ/PK - 1PK - 2 IN 1 GUMMIES - MISFITS",
|
| 220 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/jolly-rancher-grocery-candy-6-5oz-pk-1pk-2-in-1-gummies-misfits17449894976052025-04-18-15-18-17XuOJ8.jpg",
|
| 221 |
+
"link": "https://101smokeshop.com/",
|
| 222 |
+
"price": "2.25"
|
| 223 |
+
},
|
| 224 |
+
{
|
| 225 |
+
"name": "HERSHEY'S - GROCERY - CANDY - 8.5OZ/PK - 1PK - DIPPED PRETZELS - COOKIES 'N' CREME",
|
| 226 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/hershey-s-grocery-candy-8-5oz-pk-1pk-dipped-pretzels-cookies-n-creme17449897499262025-04-18-15-22-30TnsNs.jpg",
|
| 227 |
+
"link": "https://101smokeshop.com/",
|
| 228 |
+
"price": "3.75"
|
| 229 |
+
},
|
| 230 |
+
{
|
| 231 |
+
"name": "HARIBO - GROCERY - CANDY - 4.1OZ/CT - BERRY CLOUDS",
|
| 232 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/haribo-grocery-candy-4-1oz-ct-berry-clouds17438803664762025-04-05-19-12-46CkvpS.jpg",
|
| 233 |
+
"link": "https://101smokeshop.com/",
|
| 234 |
+
"price": "1.75"
|
| 235 |
+
}
|
| 236 |
+
]
|
api/trendingProducts.json
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"name": "VINUT - BEVERAGE - COCONUT WATER - CAN - 16.57OZ/CT - 24CT/CS - WITH PULP",
|
| 4 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/VINUT-BEVERAGE-COCONUT-WATER-CAN-16-57OZCT-24CTCS-WITH-PULP17562354099202025-08-26-19-10-1115rdj.jpg",
|
| 5 |
+
"link": "https://101smokeshop.com/"
|
| 6 |
+
},
|
| 7 |
+
{
|
| 8 |
+
"name": "VINUT - BEVERAGE - JUICE - CAN - 16.57OZ/CT - 24CT/CS",
|
| 9 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/VINUT-BEVERAGE-JUICE-CAN-16-57OZCT-24CTCS17562392527392025-08-26-20-14-13hHE2u.jpg",
|
| 10 |
+
"link": "https://101smokeshop.com/"
|
| 11 |
+
},
|
| 12 |
+
{
|
| 13 |
+
"name": "NAKED - BEVERAGE - JUICE - PLASTIC BOTTLE - 15.2OZ/CT - 8CT/CS",
|
| 14 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/NAKED-BEVERAGE-JUICE-PLASTIC-BOTTLE-15-2OZCT-8CTCS17551201485372025-08-13-21-22-26yW2az.jpg",
|
| 15 |
+
"link": "https://101smokeshop.com/"
|
| 16 |
+
},
|
| 17 |
+
{
|
| 18 |
+
"name": "ALANI NU - BEVERAGE - ENERGY DRINK - CAN - 12OZ/CT - 24CT/CS - ZERO SUGAR",
|
| 19 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/ALANI-NU-BEVERAGE-ENERGY-DRINK-CAN-12OZCT-24CTCS-ZERO-SUGAR17487190601762025-05-31-19-17-39GGCVx.jpg",
|
| 20 |
+
"link": "https://101smokeshop.com/"
|
| 21 |
+
},
|
| 22 |
+
{
|
| 23 |
+
"name": "DOLE - BEVERAGE - JUICE - CAN - 46OZ/CT - 12CT/CS - PINEAPPLE",
|
| 24 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/DOLE-BEVERAGE-JUICE-CAN-46OZCT-12CTCS-PINEAPPLE17482702382402025-05-26-14-37-18hAqJ1.jpg",
|
| 25 |
+
"link": "https://101smokeshop.com/"
|
| 26 |
+
},
|
| 27 |
+
{
|
| 28 |
+
"name": "SIDRAL MUNDET - BEVERAGE - SODA - GLASS BOTTLE - 12OZ/CT - 24CT/CS",
|
| 29 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/SIDRAL-MUNDET-BEVERAGE-SODA-GLASS-BOTTLE-12OZCT-24CTCS17480218025532025-05-23-17-36-41OOS2z.jpg",
|
| 30 |
+
"link": "https://101smokeshop.com/"
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"name": "FIJI - BEVERAGE - PREMIUM WATER",
|
| 34 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/FIJI-BEVERAGE-PREMIUM-WATER17480214817412025-05-23-17-31-20qe4G6.jpg",
|
| 35 |
+
"link": "https://101smokeshop.com/"
|
| 36 |
+
},
|
| 37 |
+
{
|
| 38 |
+
"name": "BAI - BEVERAGE - FLAVORED WATER - PLASTIC BOTTLE - 18OZ/CT - 12CT/CS",
|
| 39 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/BAI-BEVERAGE-FLAVORED-WATER-PLASTIC-BOTTLE-18OZCT-12CTCS17480269836952025-05-23-19-03-037aoVE.jpg",
|
| 40 |
+
"link": "https://101smokeshop.com/"
|
| 41 |
+
},
|
| 42 |
+
{
|
| 43 |
+
"name": "SMART WATER - BEVERAGE - WATER - PLASTIC BOTTLE - 33.8OZ/CT - 15CT/CS - PURELY BALANCED PH",
|
| 44 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/SMART-WATER-BEVERAGE-WATER-PLASTIC-BOTTLE-33-8OZCT-15CTCS-PURELY-BALANCED-PH17477599431542025-05-20-16-52-24N7YOB.jpg",
|
| 45 |
+
"link": "https://101smokeshop.com/"
|
| 46 |
+
},
|
| 47 |
+
{
|
| 48 |
+
"name": "SMART WATER - BEVERAGE - WATER - PLASTIC BOTTLE - 50.7OZ/CT - 12CT/CS",
|
| 49 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/SMART-WATER-BEVERAGE-WATER-PLASTIC-BOTTLE-50-7OZCT-12CTCS17477604145962025-05-20-17-00-15c6rMp.jpg",
|
| 50 |
+
"link": "https://101smokeshop.com/"
|
| 51 |
+
},
|
| 52 |
+
{
|
| 53 |
+
"name": "CRUSH - BEVERAGE - SODA - PLASTIC BOTTLE - 20OZ/CT - 24CT/CS",
|
| 54 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/CRUSH-BEVERAGE-SODA-PLASTIC-BOTTLE-20OZCT-24CTCS17473174625992025-05-15-13-57-41HM8or.jpg",
|
| 55 |
+
"link": "https://101smokeshop.com/"
|
| 56 |
+
},
|
| 57 |
+
{
|
| 58 |
+
"name": "VITA COCO - BEVERAGE - COCONUT WATER - TETRA PACK - 16.9OZ/CT - 12CT/CS",
|
| 59 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/VITA-COCO-BEVERAGE-COCONUT-WATER-TETRA-PACK-16-9OZCT-12CTCS17467976073592025-05-09-13-33-27NcQAe.png",
|
| 60 |
+
"link": "https://101smokeshop.com/"
|
| 61 |
+
},
|
| 62 |
+
{
|
| 63 |
+
"name": "NIAGARA - BEVERAGE - GALLON WATER - PLASTIC BOTTLE - 1GAL/CT - 6CT/CS",
|
| 64 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/NIAGARA-BEVERAGE-WATER-PLASTIC-BOTTLE-1GALCT-6CTCS17464830950482025-05-05-22-11-349smU2.jpg",
|
| 65 |
+
"link": "https://101smokeshop.com/"
|
| 66 |
+
},
|
| 67 |
+
{
|
| 68 |
+
"name": "DOLE - BEVERAGE - JUICE - CAN - 8OZ/CT - 24CT/CS",
|
| 69 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/dole-beverage-juice-can-8oz-ct-24ct-cs-pineapple17449240806912025-04-17-21-08-01dITAy.jpg",
|
| 70 |
+
"link": "https://101smokeshop.com/"
|
| 71 |
+
},
|
| 72 |
+
{
|
| 73 |
+
"name": "SMARTWATER - BEVERAGE - WATER - PLASTIC BOTTLE - 23.7OZ/CT - 24CT/CS - SPORTS BOTTLE",
|
| 74 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/smartwater-beverage-water-plastic-bottle-23-7oz-ct-24ct-cs-sports-bottle17443217482322025-04-10-21-49-082nSkn.jpg",
|
| 75 |
+
"link": "https://101smokeshop.com/"
|
| 76 |
+
},
|
| 77 |
+
{
|
| 78 |
+
"name": "SPORTWATER+ - BEVERAGE - ENERGY DRINK - PLASTIC BOTTLE - 20OZ/CT - 24CT/CS",
|
| 79 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/sportwater-beverage-energy-drink-plastic-bottle-20oz-ct-24ct-cs17440551866632025-04-07-19-46-273bJIN.jpg",
|
| 80 |
+
"link": "https://101smokeshop.com/"
|
| 81 |
+
},
|
| 82 |
+
{
|
| 83 |
+
"name": "GHOST - BEVERAGE - ENERGY DRINK - CAN - 16OZ/CT - 12CT/CS - ZERO SUGAR",
|
| 84 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/ghost-beverage-energy-drink-can-16oz-ct-12ct-cs17419735821242025-03-14-17-33-01IKqRx.png",
|
| 85 |
+
"link": "https://101smokeshop.com/"
|
| 86 |
+
},
|
| 87 |
+
{
|
| 88 |
+
"name": "PEPSI - BEVERAGE - SODA - PLASTIC BOTTLE - 2LT/CT - 8CT/CS",
|
| 89 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/pepsi-beverage-soda-plastic-bottle-2lt-ct-8ct-cs17412081250142025-03-05-20-55-25rWkIP.png",
|
| 90 |
+
"link": "https://101smokeshop.com/"
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"name": "MILKY WAY - BEVERAGE - CHOCOLATE DRINK - 14OZ/CT - 12CT/CS - CHOCOLATE MILK",
|
| 94 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/milky-way-beverage-chocolate-drink-14oz-ct-12ct-cs-chocolate-milk17401904093522025-02-22-02-13-307KLgY.png",
|
| 95 |
+
"link": "https://101smokeshop.com/"
|
| 96 |
+
},
|
| 97 |
+
{
|
| 98 |
+
"name": "TWIX - BEVERAGE - CHOCOLATE DRINK - 14OZ/CT - 12CT/CS - CHOCOLATE MILK",
|
| 99 |
+
"image": "https://d2p2lri02rh20e.cloudfront.net/product-images/twix-beverage-chocolate-drink-14oz-ct-12ct-cs-chocolate-milk17401906388972025-02-22-02-17-190dPEf.png",
|
| 100 |
+
"link": "https://101smokeshop.com/"
|
| 101 |
+
}
|
| 102 |
+
]
|
api/urls.py
CHANGED
|
@@ -11,4 +11,5 @@ urlpatterns = [
|
|
| 11 |
path('coupon-redeem', CouponRedeemView.as_view(), name='coupon_redeem'),
|
| 12 |
path('product-list', ProductListView.as_view(), name='product_List'),
|
| 13 |
path('best-sellers', BestSellersView.as_view(), name='best_sellers'),
|
|
|
|
| 14 |
]
|
|
|
|
| 11 |
path('coupon-redeem', CouponRedeemView.as_view(), name='coupon_redeem'),
|
| 12 |
path('product-list', ProductListView.as_view(), name='product_List'),
|
| 13 |
path('best-sellers', BestSellersView.as_view(), name='best_sellers'),
|
| 14 |
+
path('home-images', ImagesView.as_view(), name='ImagesView'),
|
| 15 |
]
|
api/views.py
CHANGED
|
@@ -16,6 +16,8 @@ authToken = '54bef1bd2916433d8f1d821a8822c377:b0be3750efa7486288df03b53076b3c59d
|
|
| 16 |
RevelUrl = "https://101smokeshop.revelup.com"
|
| 17 |
wooCommerceAuth = "consumer_key=ck_be3c4f80816fa3750154af5c100ad03e450b10b1&consumer_secret=cs_c513ff4e21e426234ca7b2b589c6a88a3749dee2"
|
| 18 |
|
|
|
|
|
|
|
| 19 |
def create_barcode_from_binary(binary_text, height=100, line_width=2):
|
| 20 |
"""
|
| 21 |
Create a barcode-like image from binary text where:
|
|
@@ -92,6 +94,9 @@ class EstablishmentListView(APIView):
|
|
| 92 |
data[i]["address"] = requests.get(urlBase + data[i]["address"], headers=headers).json()
|
| 93 |
except:
|
| 94 |
pass
|
|
|
|
|
|
|
|
|
|
| 95 |
|
| 96 |
return JsonResponse({"data": data})
|
| 97 |
|
|
@@ -119,45 +124,57 @@ def product_category(request):
|
|
| 119 |
class ProductListView(APIView):
|
| 120 |
permission_classes = [IsAuthenticated]
|
| 121 |
def get(self, request):
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
|
| 140 |
class BestSellersView(APIView):
|
| 141 |
permission_classes = [IsAuthenticated]
|
| 142 |
def get(self, request):
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
|
| 162 |
class CouponListView(APIView):
|
| 163 |
permission_classes = [IsAuthenticated]
|
|
@@ -210,4 +227,12 @@ class CouponRedeemView(APIView):
|
|
| 210 |
user.rewardPoints -= coupon.pointsNeededForRedemption
|
| 211 |
user.save()
|
| 212 |
user.activatedCoupons.add(coupon)
|
| 213 |
-
return JsonResponse({"message": "Coupon redeemed successfully"})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
RevelUrl = "https://101smokeshop.revelup.com"
|
| 17 |
wooCommerceAuth = "consumer_key=ck_be3c4f80816fa3750154af5c100ad03e450b10b1&consumer_secret=cs_c513ff4e21e426234ca7b2b589c6a88a3749dee2"
|
| 18 |
|
| 19 |
+
TrueServer = False
|
| 20 |
+
|
| 21 |
def create_barcode_from_binary(binary_text, height=100, line_width=2):
|
| 22 |
"""
|
| 23 |
Create a barcode-like image from binary text where:
|
|
|
|
| 94 |
data[i]["address"] = requests.get(urlBase + data[i]["address"], headers=headers).json()
|
| 95 |
except:
|
| 96 |
pass
|
| 97 |
+
|
| 98 |
+
data = json.dumps(data).replace(" smoke ", " ").replace("smoke", "").replace(" Smoke ", " ").replace("Smoke", "")
|
| 99 |
+
data = json.loads(data)
|
| 100 |
|
| 101 |
return JsonResponse({"data": data})
|
| 102 |
|
|
|
|
| 124 |
class ProductListView(APIView):
|
| 125 |
permission_classes = [IsAuthenticated]
|
| 126 |
def get(self, request):
|
| 127 |
+
if TrueServer:
|
| 128 |
+
url = "https://101smokeshop.com/wp-json/wc/v3/products?"+wooCommerceAuth+"&orderby=popularity"
|
| 129 |
+
|
| 130 |
+
response = requests.request("GET", url)
|
| 131 |
+
try:
|
| 132 |
+
data = response.json()
|
| 133 |
+
productData = []
|
| 134 |
+
for product in data:
|
| 135 |
+
temp={
|
| 136 |
+
"id": product["id"],
|
| 137 |
+
"name": product["name"],
|
| 138 |
+
"image": product["images"][0]["src"],
|
| 139 |
+
"link": product["permalink"]
|
| 140 |
+
}
|
| 141 |
+
productData.append(temp)
|
| 142 |
+
return JsonResponse({"data": productData})
|
| 143 |
+
except json.JSONDecodeError:
|
| 144 |
+
print(response.text)
|
| 145 |
+
else:
|
| 146 |
+
with open("./api/trendingProducts.json", "r") as f:
|
| 147 |
+
data = json.load(f)
|
| 148 |
+
return JsonResponse({"data": data})
|
| 149 |
|
| 150 |
class BestSellersView(APIView):
|
| 151 |
permission_classes = [IsAuthenticated]
|
| 152 |
def get(self, request):
|
| 153 |
+
if TrueServer:
|
| 154 |
+
url = "https://101smokeshop.com/wp-json/wc/v3/products?"+wooCommerceAuth+"&orderby=menu_order"
|
| 155 |
+
|
| 156 |
+
response = requests.request("GET", url)
|
| 157 |
+
try:
|
| 158 |
+
data = response.json()
|
| 159 |
+
best_sellers = []
|
| 160 |
+
for product in data:
|
| 161 |
+
temp={
|
| 162 |
+
"id": product["id"],
|
| 163 |
+
"name": product["name"],
|
| 164 |
+
"image": product["images"][0]["src"],
|
| 165 |
+
"link": product["permalink"],
|
| 166 |
+
"price": product["price"] if product["price"] else product["regular_price"] if product["regular_price"] else product["sale_price"] if product["sale_price"] else 0
|
| 167 |
+
}
|
| 168 |
+
best_sellers.append(temp)
|
| 169 |
+
print(best_sellers)
|
| 170 |
+
return JsonResponse({"data": best_sellers})
|
| 171 |
+
except json.JSONDecodeError:
|
| 172 |
+
print(response.text)
|
| 173 |
+
return JsonResponse({"data": []})
|
| 174 |
+
else:
|
| 175 |
+
with open("./api/bestSellers.json", "r") as f:
|
| 176 |
+
data = json.load(f)
|
| 177 |
+
return JsonResponse({"data": data})
|
| 178 |
|
| 179 |
class CouponListView(APIView):
|
| 180 |
permission_classes = [IsAuthenticated]
|
|
|
|
| 227 |
user.rewardPoints -= coupon.pointsNeededForRedemption
|
| 228 |
user.save()
|
| 229 |
user.activatedCoupons.add(coupon)
|
| 230 |
+
return JsonResponse({"message": "Coupon redeemed successfully"})
|
| 231 |
+
|
| 232 |
+
class ImagesView(APIView):
|
| 233 |
+
permission_classes = []
|
| 234 |
+
def get(self, request):
|
| 235 |
+
catImages = ["https://d2p2lri02rh20e.cloudfront.net/product-images/cyrine-cartridgebattery-biride-510voltage-5ctbx1711652088702.webp", "https://d2p2lri02rh20e.cloudfront.net/product-images/geekvape-an-2-vape-device-kit-e-juice-device-1100mah1703199105406.png", "https://d2p2lri02rh20e.cloudfront.net/product-images/pod-juice-e-liquid-nicotine-tfn-3mg-ml-100ml-ct1713545069848.webp", "https://d2p2lri02rh20e.cloudfront.net/product-images/free-noms-e-liquid-nicotine-ice-3mg-ml-120ml-ct1713370750626.webp", "https://d2p2lri02rh20e.cloudfront.net/product-images/candy-king-e-liquid-salt-nicotine-ice-35mg-ml-30ml-ct1713363531128.", "https://d2p2lri02rh20e.cloudfront.net/product-images/air-factory-e-liquid-nicotine-ice-3mg-ml-60ml-ct1713360735189.webp", "https://d2p2lri02rh20e.cloudfront.net/product-images/rc-upload-1699734904189-42--mints_e_liquid_nicotine_3mg_60ml_2ct_bx.", "https://d2p2lri02rh20e.cloudfront.net/product-images/pod-juice-e-liquid-nicotine-tfn-3mg-ml-100ml-ct1713545069848.webp", "https://d2p2lri02rh20e.cloudfront.net/product-images/recon-4g-by-wulf-mods-vaporizer-device-kit-9ct-bx1717079743309.png", "https://d2p2lri02rh20e.cloudfront.net/product-images/ganling-vaporizerdevicekit-withbluetooth-gunv2nu1709414588915.webp", "https://d2p2lri02rh20e.cloudfront.net/product-images/ooze-brink-1800mah1708709429277.webp", "https://d2p2lri02rh20e.cloudfront.net/product-images/puffco-coloredglass-replacement1704843967439.png", "https://d2p2lri02rh20e.cloudfront.net/product-images/recon-4g-by-wulf-mods-vaporizer-device-kit-9ct-bx1717079743309.png", "https://d2p2lri02rh20e.cloudfront.net/product-images/nbc-glasspipe-acc-nectar-collecter-4-5-1ct1722177340675.png", "https://d2p2lri02rh20e.cloudfront.net/product-images/getlost-glasspipe-waterpipe-15-1ct-ray-gun1721248337222.png", "https://d2p2lri02rh20e.cloudfront.net/product-images/nbc-hookah-1-hose-19-1ct-robot1720721034430.png", "https://d2p2lri02rh20e.cloudfront.net/product-images/nbc-hookah-kit-32-1ct-pressure-gauge-with-tap1720722809372.png", "https://d2p2lri02rh20e.cloudfront.net/product-images/nbc-hookah-kit-1h-21-1ct-panther-black1719261388482.png", "https://d2p2lri02rh20e.cloudfront.net/product-images/zebrasmoke-hookahkit-1h20-1ct-pistol1711749911268.webp", "https://d2p2lri02rh20e.cloudfront.net/product-images/mya-hookah-acc-qt-base-5.5-1ct1702596340867.png", "https://d2p2lri02rh20e.cloudfront.net/product-images/nbc-hookah-1-hose-19-1ct-robot1720721034430.png", "https://d2p2lri02rh20e.cloudfront.net/product-images/nbc-hookah-kit-32-1ct-pressure-gauge-with-tap1720722809372.png", "https://d2p2lri02rh20e.cloudfront.net/product-images/rc-upload-1674168341195-2--fumari_shisha_100gm.webp", "https://d2p2lri02rh20e.cloudfront.net/product-images/rc-upload-1680990149489-2--eternal_smoke_al_flavored_molasses_250gm.", "https://d2p2lri02rh20e.cloudfront.net/product-images/rc-upload-1674161380200-2--starbuzz_bold.webp", "https://d2p2lri02rh20e.cloudfront.net/product-images/rc-upload-1674167817817-3--ror_shisha.webp", "https://d2p2lri02rh20e.cloudfront.net/product-images/rc-upload-1674168341195-2--fumari_shisha_100gm.webp", "https://d2p2lri02rh20e.cloudfront.net/product-images/rc-upload-1680990149489-2--eternal_smoke_al_flavored_molasses_250gm.", "https://d2p2lri02rh20e.cloudfront.net/product-images/rc-upload-1697039328485-2--coconara_hookah_charcoal_60ct_pk.png", "https://d2p2lri02rh20e.cloudfront.net/product-images/rc-upload-1682604308875-2--black_owl_charcoal_31mmm_xl_1kg_36ct_bx.", "https://d2p2lri02rh20e.cloudfront.net/product-images/titanium-flats-hookah-charcoal-108ct-bx-coconut1701901803262.png", "https://d2p2lri02rh20e.cloudfront.net/product-images/rc-upload-1688161551426-2--charcoblaze_150ct.webp", "https://d2p2lri02rh20e.cloudfront.net/product-images/rc-upload-1697039328485-2--coconara_hookah_charcoal_60ct_pk.png", "https://d2p2lri02rh20e.cloudfront.net/product-images/rc-upload-1682604308875-2--black_owl_charcoal_31mmm_xl_1kg_36ct_bx.", "https://d2p2lri02rh20e.cloudfront.net/product-images/get-lost-smoking-acc-4-in-1-glow-jar-1ct-galaxy1721249518049.png", "https://d2p2lri02rh20e.cloudfront.net/product-images/get-lost-smoking-acc-kit-all-in-one-7pc-pk-1pk1717509223381.png", "https://d2p2lri02rh20e.cloudfront.net/product-images/v-syndicate-smoking-acc-rolling-tray-metal-1ct-medium1714234747472.", "https://d2p2lri02rh20e.cloudfront.net/product-images/get-lost-smoking-acc-4-in-1-glow-jar-1ct-galaxy1721249518049.png"]
|
| 236 |
+
imageOrignal = ["/static/home/1.jpg", "/static/home/2.jpg", "/static/home/3.jpg", "/static/home/4.jpg", "/static/home/5.jpg"]
|
| 237 |
+
imageGas = ["/static/home/1.png", "/static/home/2.png", "/static/home/3.png", "/static/home/4.png", "/static/home/5.png"]
|
| 238 |
+
return JsonResponse({"data": {"catImages": catImages, "posterImage": imageGas if not TrueServer else imageOrignal}})
|
authentication/migrations/__pycache__/0001_initial.cpython-311.pyc
ADDED
|
Binary file (4.53 kB). View file
|
|
|
authentication/migrations/__pycache__/0002_alter_userdata_coupons_alter_userdata_otp.cpython-311.pyc
ADDED
|
Binary file (1.05 kB). View file
|
|
|
authentication/migrations/__pycache__/0003_alter_coupon_expirydate.cpython-311.pyc
ADDED
|
Binary file (864 Bytes). View file
|
|
|
authentication/migrations/__pycache__/0004_coupon_discription.cpython-311.pyc
ADDED
|
Binary file (829 Bytes). View file
|
|
|
authentication/migrations/__pycache__/0005_userdata_refcode.cpython-311.pyc
ADDED
|
Binary file (841 Bytes). View file
|
|
|
authentication/migrations/__pycache__/0006_userdata_activatedcoupons.cpython-311.pyc
ADDED
|
Binary file (897 Bytes). View file
|
|
|
authentication/migrations/__pycache__/0007_userdata_revelid.cpython-311.pyc
ADDED
|
Binary file (850 Bytes). View file
|
|
|
authentication/migrations/__pycache__/0008_alter_userdata_pincode.cpython-311.pyc
ADDED
|
Binary file (834 Bytes). View file
|
|
|
authentication/migrations/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (180 Bytes). View file
|
|
|
authentication/views copy.py
ADDED
|
@@ -0,0 +1,441 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# authentication/views.py
|
| 2 |
+
|
| 3 |
+
from django.contrib.auth.models import User
|
| 4 |
+
from django.contrib.auth import authenticate
|
| 5 |
+
from django.http import JsonResponse
|
| 6 |
+
from rest_framework.views import APIView
|
| 7 |
+
from django.views.decorators.csrf import csrf_exempt
|
| 8 |
+
import json
|
| 9 |
+
from rest_framework_simplejwt.tokens import RefreshToken
|
| 10 |
+
from rest_framework.permissions import IsAuthenticated, AllowAny
|
| 11 |
+
from django.core.mail import send_mail
|
| 12 |
+
import random
|
| 13 |
+
import requests
|
| 14 |
+
from django.utils import timezone
|
| 15 |
+
from datetime import timedelta
|
| 16 |
+
from .models import UserData
|
| 17 |
+
import uuid
|
| 18 |
+
|
| 19 |
+
# In-memory storage for OTPs (use a persistent storage in production)
|
| 20 |
+
OTP_STORAGE = {}
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
class RegisterView(APIView):
|
| 24 |
+
permission_classes = [AllowAny]
|
| 25 |
+
|
| 26 |
+
def post(self, request):
|
| 27 |
+
try:
|
| 28 |
+
data = json.loads(request.body)
|
| 29 |
+
email = data.get('email')
|
| 30 |
+
password = data.get('password')
|
| 31 |
+
first_name = data.get('first_name')
|
| 32 |
+
last_name = data.get('last_name')
|
| 33 |
+
phone = data.get('phone')
|
| 34 |
+
birthDate = data.get('birthDate')
|
| 35 |
+
gender = data.get('gender', 'male')
|
| 36 |
+
streetName = data.get('streetName')
|
| 37 |
+
city = data.get('city')
|
| 38 |
+
state = data.get('state')
|
| 39 |
+
country = data.get('country')
|
| 40 |
+
pincode = data.get('pincode')
|
| 41 |
+
getUpdates = data.get('getUpdates', False)
|
| 42 |
+
birthDate = birthDate.split('T')[0]
|
| 43 |
+
|
| 44 |
+
if User.objects.filter(email=email).exists():
|
| 45 |
+
return JsonResponse({'error': 'Email already exists'}, status=400)
|
| 46 |
+
|
| 47 |
+
user = User.objects.create_user(
|
| 48 |
+
username=email,
|
| 49 |
+
email=email,
|
| 50 |
+
password=password,
|
| 51 |
+
first_name=first_name,
|
| 52 |
+
last_name=last_name
|
| 53 |
+
)
|
| 54 |
+
user.save()
|
| 55 |
+
|
| 56 |
+
userDataObj = UserData.objects.create(
|
| 57 |
+
user=user,
|
| 58 |
+
phone=phone,
|
| 59 |
+
refCode=phone,
|
| 60 |
+
birthDate=birthDate,
|
| 61 |
+
gender=gender,
|
| 62 |
+
streetName=streetName,
|
| 63 |
+
city=city,
|
| 64 |
+
state=state,
|
| 65 |
+
country=country,
|
| 66 |
+
pincode=pincode,
|
| 67 |
+
isSubscribed=getUpdates
|
| 68 |
+
)
|
| 69 |
+
|
| 70 |
+
otp = random.randint(100000, 999999)
|
| 71 |
+
OTP_STORAGE[email] = {
|
| 72 |
+
'otp': otp,
|
| 73 |
+
'expires_at': timezone.now() + timedelta(minutes=10) # OTP valid for 10 minutes
|
| 74 |
+
}
|
| 75 |
+
print(otp)
|
| 76 |
+
# Send OTP via email
|
| 77 |
+
# send_mail(
|
| 78 |
+
# 'Password Reset OTP',
|
| 79 |
+
# f'Your OTP for password reset is {otp}',
|
| 80 |
+
# 'noreply@example.com', # Replace with your email
|
| 81 |
+
# [email],
|
| 82 |
+
# fail_silently=False,
|
| 83 |
+
# )
|
| 84 |
+
|
| 85 |
+
# Add user to Revel system
|
| 86 |
+
revel_payload = json.dumps({
|
| 87 |
+
"accept_checks": False,
|
| 88 |
+
"account_balance": None,
|
| 89 |
+
"account_limit": None,
|
| 90 |
+
"active": True,
|
| 91 |
+
"address": streetName,
|
| 92 |
+
"birth_date": birthDate,
|
| 93 |
+
"cc_exp": "03/22",
|
| 94 |
+
"cc_first_name": first_name,
|
| 95 |
+
"cc_last_name": last_name,
|
| 96 |
+
"cc_last_4_digits": "1111",
|
| 97 |
+
"city": city,
|
| 98 |
+
"company_name": "B-Company",
|
| 99 |
+
# "contract_expiration": "2019-05-16T00:00:00",
|
| 100 |
+
"created_by": "/enterprise/User/9393/",
|
| 101 |
+
"created_date": timezone.now().isoformat(),
|
| 102 |
+
"customer_groups": [],
|
| 103 |
+
"deleted": False,
|
| 104 |
+
"discount": 0,
|
| 105 |
+
"email": email,
|
| 106 |
+
"email_opt_in": getUpdates,
|
| 107 |
+
# "exp_date": "1919-05-16T00:00:00",
|
| 108 |
+
"expensify_account": f'{{"{email}":["193"]}}',
|
| 109 |
+
"first_name": first_name,
|
| 110 |
+
"gender": 0 if gender.lower() == 'male' else 1,
|
| 111 |
+
"gift_card_numbers": [],
|
| 112 |
+
"is_visitor": False,
|
| 113 |
+
"last_name": last_name,
|
| 114 |
+
"lic_number": "EAK173",
|
| 115 |
+
"loyalty_number": None,
|
| 116 |
+
"loyalty_ref_id": "",
|
| 117 |
+
"notes": "New Customer",
|
| 118 |
+
"ok_to_email": False,
|
| 119 |
+
"past_due": 0,
|
| 120 |
+
"phone_number": phone,
|
| 121 |
+
"phone_opt_in": getUpdates,
|
| 122 |
+
"pin": "",
|
| 123 |
+
"post_opt_in": False,
|
| 124 |
+
"ref_number": "1731-147709",
|
| 125 |
+
"reward_card_numbers": [],
|
| 126 |
+
"source": None,
|
| 127 |
+
"state": state,
|
| 128 |
+
"tax_exempt": False,
|
| 129 |
+
# "tax_location": "CA Orange County",
|
| 130 |
+
# "third_party_id": "1731147709",
|
| 131 |
+
"title": "Mr" if gender == "male" else "Ms",
|
| 132 |
+
"total_purchases": 0,
|
| 133 |
+
"total_visits": 0,
|
| 134 |
+
"track_as_company": True,
|
| 135 |
+
"type": 1,
|
| 136 |
+
"updated_by": "/enterprise/User/9393/",
|
| 137 |
+
"updated_date": timezone.now().isoformat(),
|
| 138 |
+
"uuid": uuid.uuid4().hex,
|
| 139 |
+
"vehicles": [],
|
| 140 |
+
"version_date": timezone.now().isoformat(),
|
| 141 |
+
"zipcode": pincode
|
| 142 |
+
})
|
| 143 |
+
revel_headers = {
|
| 144 |
+
'content-type': 'application/json',
|
| 145 |
+
'API-AUTHENTICATION': 'fab57498544244e38bfc2741880f8d61:ed9628295b0642e1b38308795c9cdadd58012df4ceb84a3b9d441c017a1eeac0'
|
| 146 |
+
}
|
| 147 |
+
revel_response = requests.post("https://101smokeshop-uat.revelup.com/resources/Customer/", headers=revel_headers, data=revel_payload)
|
| 148 |
+
# print(revel_response.json())
|
| 149 |
+
|
| 150 |
+
userDataObj.revelId = revel_response.json()['id']
|
| 151 |
+
userDataObj.save()
|
| 152 |
+
refresh = RefreshToken.for_user(user)
|
| 153 |
+
userData = {}
|
| 154 |
+
userData['email'] = user.email
|
| 155 |
+
userData['first_name'] = user.first_name
|
| 156 |
+
userData['last_name'] = user.last_name
|
| 157 |
+
userData['access'] = str(refresh.access_token)
|
| 158 |
+
userData['refresh'] = str(refresh)
|
| 159 |
+
userData["phone"] = userDataObj.phone
|
| 160 |
+
userData["refCode"] = userDataObj.refCode
|
| 161 |
+
userData["birthDate"] = userDataObj.birthDate
|
| 162 |
+
userData["gender"] = userDataObj.gender
|
| 163 |
+
userData["streetName"] = userDataObj.streetName
|
| 164 |
+
userData["city"] = userDataObj.city
|
| 165 |
+
userData["state"] = userDataObj.state
|
| 166 |
+
userData["country"] = userDataObj.country
|
| 167 |
+
userData["pincode"] = userDataObj.pincode
|
| 168 |
+
userData["rewardPoints"] = userDataObj.rewardPoints
|
| 169 |
+
userData["isVerified"] = userDataObj.isVerified
|
| 170 |
+
userData["isSubscribed"] = userDataObj.isSubscribed
|
| 171 |
+
userData["isBlocked"] = userDataObj.isBlocked
|
| 172 |
+
userData["isDeleted"] = userDataObj.isDeleted
|
| 173 |
+
return JsonResponse(userData, status=200)
|
| 174 |
+
except Exception as e:
|
| 175 |
+
print(e)
|
| 176 |
+
return JsonResponse({'error': str(e)}, status=400)
|
| 177 |
+
|
| 178 |
+
|
| 179 |
+
class LoginView(APIView):
|
| 180 |
+
permission_classes = [AllowAny]
|
| 181 |
+
|
| 182 |
+
def post(self, request):
|
| 183 |
+
try:
|
| 184 |
+
data = json.loads(request.body)
|
| 185 |
+
username = data.get('username')
|
| 186 |
+
password = data.get('password')
|
| 187 |
+
|
| 188 |
+
user = authenticate(username=username, password=password)
|
| 189 |
+
if user is not None:
|
| 190 |
+
refresh = RefreshToken.for_user(user)
|
| 191 |
+
userDataObj = UserData.objects.get(user=user)
|
| 192 |
+
userData = {}
|
| 193 |
+
userData['email'] = user.email
|
| 194 |
+
userData['first_name'] = user.first_name
|
| 195 |
+
userData['last_name'] = user.last_name
|
| 196 |
+
userData['access'] = str(refresh.access_token)
|
| 197 |
+
userData['refresh'] = str(refresh)
|
| 198 |
+
userData["phone"] = userDataObj.phone
|
| 199 |
+
userData["refCode"] = userDataObj.refCode
|
| 200 |
+
userData["birthDate"] = userDataObj.birthDate
|
| 201 |
+
userData["gender"] = userDataObj.gender
|
| 202 |
+
userData["streetName"] = userDataObj.streetName
|
| 203 |
+
userData["city"] = userDataObj.city
|
| 204 |
+
userData["state"] = userDataObj.state
|
| 205 |
+
userData["country"] = userDataObj.country
|
| 206 |
+
userData["pincode"] = userDataObj.pincode
|
| 207 |
+
userData["rewardPoints"] = userDataObj.rewardPoints
|
| 208 |
+
userData["isVerified"] = userDataObj.isVerified
|
| 209 |
+
userData["isSubscribed"] = userDataObj.isSubscribed
|
| 210 |
+
userData["isBlocked"] = userDataObj.isBlocked
|
| 211 |
+
userData["isDeleted"] = userDataObj.isDeleted
|
| 212 |
+
return JsonResponse(userData, status=200)
|
| 213 |
+
else:
|
| 214 |
+
return JsonResponse({'error': 'Invalid credentials'}, status=401)
|
| 215 |
+
except Exception as e:
|
| 216 |
+
print(e)
|
| 217 |
+
return JsonResponse({'error': str(e)}, status=400)
|
| 218 |
+
|
| 219 |
+
|
| 220 |
+
class UserDetailView(APIView):
|
| 221 |
+
permission_classes = [IsAuthenticated]
|
| 222 |
+
|
| 223 |
+
def get(self, request):
|
| 224 |
+
user = request.user
|
| 225 |
+
refresh = RefreshToken.for_user(user)
|
| 226 |
+
userDataObj = UserData.objects.get(user=user)
|
| 227 |
+
userData = {}
|
| 228 |
+
userData['email'] = user.email
|
| 229 |
+
userData['access'] = str(refresh.access_token)
|
| 230 |
+
userData['refresh'] = str(refresh)
|
| 231 |
+
userData['first_name'] = user.first_name
|
| 232 |
+
userData['last_name'] = user.last_name
|
| 233 |
+
userData["phone"] = userDataObj.phone
|
| 234 |
+
userData["refCode"] = userDataObj.refCode
|
| 235 |
+
userData["birthDate"] = userDataObj.birthDate
|
| 236 |
+
userData["gender"] = userDataObj.gender
|
| 237 |
+
userData["streetName"] = userDataObj.streetName
|
| 238 |
+
userData["city"] = userDataObj.city
|
| 239 |
+
userData["state"] = userDataObj.state
|
| 240 |
+
userData["country"] = userDataObj.country
|
| 241 |
+
userData["pincode"] = userDataObj.pincode
|
| 242 |
+
userData["rewardPoints"] = userDataObj.rewardPoints
|
| 243 |
+
userData["isVerified"] = userDataObj.isVerified
|
| 244 |
+
userData["isSubscribed"] = userDataObj.isSubscribed
|
| 245 |
+
userData["isBlocked"] = userDataObj.isBlocked
|
| 246 |
+
userData["isDeleted"] = userDataObj.isDeleted
|
| 247 |
+
return JsonResponse(userData, status=200)
|
| 248 |
+
|
| 249 |
+
def post(self, request):
|
| 250 |
+
try:
|
| 251 |
+
user = request.user
|
| 252 |
+
userDataObj = UserData.objects.get(user=user)
|
| 253 |
+
data = json.loads(request.body)
|
| 254 |
+
user.email = data.get('email', user.email)
|
| 255 |
+
user.first_name = data.get('first_name', user.first_name)
|
| 256 |
+
user.last_name = data.get('last_name', user.last_name)
|
| 257 |
+
userDataObj.phone = data.get('phone', userDataObj.phone)
|
| 258 |
+
userDataObj.refCode = data.get('phone', userDataObj.phone)
|
| 259 |
+
userDataObj.birthDate = data.get('birthDate', userDataObj.birthDate).split('T')[0]
|
| 260 |
+
userDataObj.gender = data.get('gender', userDataObj.gender)
|
| 261 |
+
userDataObj.streetName = data.get('streetName', userDataObj.streetName)
|
| 262 |
+
userDataObj.city = data.get('city', userDataObj.city)
|
| 263 |
+
userDataObj.state = data.get('state', userDataObj.state)
|
| 264 |
+
userDataObj.country = data.get('country', userDataObj.country)
|
| 265 |
+
userDataObj.pincode = data.get('pincode', userDataObj.pincode)
|
| 266 |
+
user.save()
|
| 267 |
+
userDataObj.save()
|
| 268 |
+
userData = {}
|
| 269 |
+
refresh = RefreshToken.for_user(user)
|
| 270 |
+
userData['email'] = user.email
|
| 271 |
+
userData['access'] = str(refresh.access_token)
|
| 272 |
+
userData['refresh'] = str(refresh)
|
| 273 |
+
userData['first_name'] = user.first_name
|
| 274 |
+
userData['last_name'] = user.last_name
|
| 275 |
+
userData["phone"] = userDataObj.phone
|
| 276 |
+
userData["refCode"] = userDataObj.refCode
|
| 277 |
+
userData["birthDate"] = userDataObj.birthDate
|
| 278 |
+
userData["gender"] = userDataObj.gender
|
| 279 |
+
userData["streetName"] = userDataObj.streetName
|
| 280 |
+
userData["city"] = userDataObj.city
|
| 281 |
+
userData["state"] = userDataObj.state
|
| 282 |
+
userData["country"] = userDataObj.country
|
| 283 |
+
userData["pincode"] = userDataObj.pincode
|
| 284 |
+
userData["rewardPoints"] = userDataObj.rewardPoints
|
| 285 |
+
userData["isVerified"] = userDataObj.isVerified
|
| 286 |
+
userData["isSubscribed"] = userDataObj.isSubscribed
|
| 287 |
+
userData["isBlocked"] = userDataObj.isBlocked
|
| 288 |
+
userData["isDeleted"] = userDataObj.isDeleted
|
| 289 |
+
return JsonResponse({'message': 'User data updated successfully', "data": userData}, status=200)
|
| 290 |
+
except Exception as e:
|
| 291 |
+
return JsonResponse({'error': str(e)}, status=400)
|
| 292 |
+
|
| 293 |
+
|
| 294 |
+
class LogoutView(APIView):
|
| 295 |
+
permission_classes = [IsAuthenticated]
|
| 296 |
+
|
| 297 |
+
def post(self, request):
|
| 298 |
+
refresh_token = request.data.get('refresh')
|
| 299 |
+
if not refresh_token:
|
| 300 |
+
return JsonResponse({
|
| 301 |
+
'error': 'Refresh token is required',
|
| 302 |
+
'status': 'error'
|
| 303 |
+
}, status=400)
|
| 304 |
+
else:
|
| 305 |
+
try:
|
| 306 |
+
refresh = RefreshToken(refresh_token)
|
| 307 |
+
refresh.blacklist()
|
| 308 |
+
return JsonResponse({
|
| 309 |
+
'status': 'success',
|
| 310 |
+
'message': 'Successfully logged out'
|
| 311 |
+
})
|
| 312 |
+
except:
|
| 313 |
+
return JsonResponse({
|
| 314 |
+
"error": "Invalid token",
|
| 315 |
+
"status": "error"
|
| 316 |
+
}, status=400)
|
| 317 |
+
|
| 318 |
+
|
| 319 |
+
class RequestPasswordResetView(APIView):
|
| 320 |
+
authentication_classes = ()
|
| 321 |
+
permission_classes = () # Allow any
|
| 322 |
+
|
| 323 |
+
def post(self, request):
|
| 324 |
+
try:
|
| 325 |
+
data = json.loads(request.body)
|
| 326 |
+
email = data.get('email')
|
| 327 |
+
if not email:
|
| 328 |
+
return JsonResponse({'error': 'Email is required'}, status=400)
|
| 329 |
+
try:
|
| 330 |
+
user = User.objects.get(email=email)
|
| 331 |
+
except User.DoesNotExist:
|
| 332 |
+
return JsonResponse({'error': 'User with this email does not exist'}, status=400)
|
| 333 |
+
|
| 334 |
+
# Generate OTP
|
| 335 |
+
otp = random.randint(100000, 999999)
|
| 336 |
+
OTP_STORAGE[email] = {
|
| 337 |
+
'otp': otp,
|
| 338 |
+
'expires_at': timezone.now() + timedelta(minutes=10) # OTP valid for 10 minutes
|
| 339 |
+
}
|
| 340 |
+
print(otp)
|
| 341 |
+
# Send OTP via email
|
| 342 |
+
send_mail(
|
| 343 |
+
'Password Reset OTP',
|
| 344 |
+
f'Your OTP for password reset is {otp}',
|
| 345 |
+
'noreply@example.com', # Replace with your email
|
| 346 |
+
[email],
|
| 347 |
+
fail_silently=False,
|
| 348 |
+
)
|
| 349 |
+
|
| 350 |
+
return JsonResponse({'message': 'OTP sent to email'}, status=200)
|
| 351 |
+
except Exception as e:
|
| 352 |
+
return JsonResponse({'error': str(e)}, status=400)
|
| 353 |
+
|
| 354 |
+
|
| 355 |
+
class ResendOTPView(APIView):
|
| 356 |
+
authentication_classes = ()
|
| 357 |
+
permission_classes = () # Allow any
|
| 358 |
+
|
| 359 |
+
def post(self, request):
|
| 360 |
+
try:
|
| 361 |
+
data = json.loads(request.body)
|
| 362 |
+
email = data.get('email')
|
| 363 |
+
if not email:
|
| 364 |
+
return JsonResponse({'error': 'Email is required'}, status=400)
|
| 365 |
+
try:
|
| 366 |
+
user = User.objects.get(email=email)
|
| 367 |
+
except User.DoesNotExist:
|
| 368 |
+
return JsonResponse({'error': 'User with this email does not exist'}, status=400)
|
| 369 |
+
|
| 370 |
+
# Generate new OTP
|
| 371 |
+
otp = random.randint(100000, 999999)
|
| 372 |
+
OTP_STORAGE[email] = {
|
| 373 |
+
'otp': otp,
|
| 374 |
+
'expires_at': timezone.now() + timedelta(minutes=10) # OTP valid for 10 minutes
|
| 375 |
+
}
|
| 376 |
+
print(otp)
|
| 377 |
+
# Send OTP via email
|
| 378 |
+
send_mail(
|
| 379 |
+
'Password Reset OTP',
|
| 380 |
+
f'Your new OTP for password reset is {otp}',
|
| 381 |
+
'noreply@example.com', # Replace with your email
|
| 382 |
+
[email],
|
| 383 |
+
fail_silently=False,
|
| 384 |
+
)
|
| 385 |
+
|
| 386 |
+
return JsonResponse({'message': 'OTP resent to email'}, status=200)
|
| 387 |
+
except Exception as e:
|
| 388 |
+
return JsonResponse({'error': str(e)}, status=400)
|
| 389 |
+
|
| 390 |
+
|
| 391 |
+
class ResetPasswordView(APIView):
|
| 392 |
+
authentication_classes = ()
|
| 393 |
+
permission_classes = () # Allow any
|
| 394 |
+
|
| 395 |
+
def post(self, request):
|
| 396 |
+
try:
|
| 397 |
+
data = json.loads(request.body)
|
| 398 |
+
email = data.get('email')
|
| 399 |
+
otp = data.get('otp')
|
| 400 |
+
new_password = data.get('new_password')
|
| 401 |
+
|
| 402 |
+
if not all([email, otp, new_password]):
|
| 403 |
+
return JsonResponse({'error': 'All fields are required'}, status=400)
|
| 404 |
+
|
| 405 |
+
otp_record = OTP_STORAGE.get(email)
|
| 406 |
+
if not otp_record:
|
| 407 |
+
return JsonResponse({'error': 'OTP not found. Please request a new one.'}, status=400)
|
| 408 |
+
|
| 409 |
+
if timezone.now() > otp_record['expires_at']:
|
| 410 |
+
del OTP_STORAGE[email]
|
| 411 |
+
return JsonResponse({'error': 'OTP has expired. Please request a new one.'}, status=400)
|
| 412 |
+
|
| 413 |
+
if int(otp) != otp_record['otp']:
|
| 414 |
+
return JsonResponse({'error': 'Invalid OTP'}, status=400)
|
| 415 |
+
|
| 416 |
+
try:
|
| 417 |
+
user = User.objects.get(email=email)
|
| 418 |
+
except User.DoesNotExist:
|
| 419 |
+
return JsonResponse({'error': 'User with this email does not exist'}, status=400)
|
| 420 |
+
|
| 421 |
+
user.set_password(new_password)
|
| 422 |
+
user.save()
|
| 423 |
+
|
| 424 |
+
# Remove OTP after successful reset
|
| 425 |
+
del OTP_STORAGE[email]
|
| 426 |
+
|
| 427 |
+
return JsonResponse({'message': 'Password reset successful'}, status=200)
|
| 428 |
+
except Exception as e:
|
| 429 |
+
return JsonResponse({'error': str(e)}, status=400)
|
| 430 |
+
|
| 431 |
+
|
| 432 |
+
class refreshTokenView(APIView):
|
| 433 |
+
def post(self, request):
|
| 434 |
+
try:
|
| 435 |
+
data = json.loads(request.body)
|
| 436 |
+
refresh = data.get('refresh')
|
| 437 |
+
token = RefreshToken(refresh)
|
| 438 |
+
access = str(token.access_token)
|
| 439 |
+
return JsonResponse({'access': access}, status=200)
|
| 440 |
+
except Exception as e:
|
| 441 |
+
return JsonResponse({'error': str(e)}, status=400)
|
authentication/views.py
CHANGED
|
@@ -18,6 +18,10 @@ import uuid
|
|
| 18 |
|
| 19 |
# In-memory storage for OTPs (use a persistent storage in production)
|
| 20 |
OTP_STORAGE = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
|
| 22 |
|
| 23 |
class RegisterView(APIView):
|
|
@@ -184,34 +188,94 @@ class LoginView(APIView):
|
|
| 184 |
data = json.loads(request.body)
|
| 185 |
username = data.get('username')
|
| 186 |
password = data.get('password')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 187 |
|
| 188 |
-
|
| 189 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 190 |
refresh = RefreshToken.for_user(user)
|
| 191 |
userDataObj = UserData.objects.get(user=user)
|
| 192 |
-
userData = {
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
|
|
|
|
|
|
| 212 |
return JsonResponse(userData, status=200)
|
| 213 |
else:
|
| 214 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
except Exception as e:
|
| 216 |
print(e)
|
| 217 |
return JsonResponse({'error': str(e)}, status=400)
|
|
|
|
| 18 |
|
| 19 |
# In-memory storage for OTPs (use a persistent storage in production)
|
| 20 |
OTP_STORAGE = {}
|
| 21 |
+
authToken = '54bef1bd2916433d8f1d821a8822c377:b0be3750efa7486288df03b53076b3c59d710d9f85a34f1a9594d08dda4c4b61'
|
| 22 |
+
RevelUrl = "https://101smokeshop.revelup.com"
|
| 23 |
+
wooCommerceAuth = "consumer_key=ck_be3c4f80816fa3750154af5c100ad03e450b10b1&consumer_secret=cs_c513ff4e21e426234ca7b2b589c6a88a3749dee2"
|
| 24 |
+
|
| 25 |
|
| 26 |
|
| 27 |
class RegisterView(APIView):
|
|
|
|
| 188 |
data = json.loads(request.body)
|
| 189 |
username = data.get('username')
|
| 190 |
password = data.get('password')
|
| 191 |
+
print(username, password)
|
| 192 |
+
# First try WordPress authentication
|
| 193 |
+
wp_url = "https://101smokeshop.com/wp-json/jwt-auth/v1/token"
|
| 194 |
+
wp_payload = {
|
| 195 |
+
"username": username,
|
| 196 |
+
"password": password
|
| 197 |
+
}
|
| 198 |
+
wp_headers = {
|
| 199 |
+
'Content-Type': 'application/json'
|
| 200 |
+
}
|
| 201 |
|
| 202 |
+
wp_response = requests.post(wp_url, headers=wp_headers, json=wp_payload)
|
| 203 |
+
wp_data = wp_response.json()
|
| 204 |
+
print(wp_data)
|
| 205 |
+
if wp_response.status_code == 200 and 'token' in wp_data:
|
| 206 |
+
# WordPress authentication successful, get or create user
|
| 207 |
+
try:
|
| 208 |
+
user = User.objects.get(email=wp_data['user_email'])
|
| 209 |
+
except User.DoesNotExist:
|
| 210 |
+
# Create user if doesn't exist
|
| 211 |
+
user = User.objects.create_user(
|
| 212 |
+
username=wp_data['user_email'],
|
| 213 |
+
email=wp_data['user_email'],
|
| 214 |
+
first_name=wp_data['user_nicename'],
|
| 215 |
+
)
|
| 216 |
+
# Create associated UserData
|
| 217 |
+
UserData.objects.create(
|
| 218 |
+
user=user,
|
| 219 |
+
phone='',
|
| 220 |
+
refCode='',
|
| 221 |
+
)
|
| 222 |
+
|
| 223 |
+
# Generate JWT token and return user data
|
| 224 |
refresh = RefreshToken.for_user(user)
|
| 225 |
userDataObj = UserData.objects.get(user=user)
|
| 226 |
+
userData = {
|
| 227 |
+
'email': user.email,
|
| 228 |
+
'first_name': user.first_name,
|
| 229 |
+
'last_name': user.last_name,
|
| 230 |
+
'access': str(refresh.access_token),
|
| 231 |
+
'refresh': str(refresh),
|
| 232 |
+
'wp_token': wp_data['token'],
|
| 233 |
+
"phone": userDataObj.phone,
|
| 234 |
+
"refCode": userDataObj.refCode,
|
| 235 |
+
"birthDate": userDataObj.birthDate,
|
| 236 |
+
"gender": userDataObj.gender,
|
| 237 |
+
"streetName": userDataObj.streetName,
|
| 238 |
+
"city": userDataObj.city,
|
| 239 |
+
"state": userDataObj.state,
|
| 240 |
+
"country": userDataObj.country,
|
| 241 |
+
"pincode": userDataObj.pincode,
|
| 242 |
+
"rewardPoints": userDataObj.rewardPoints,
|
| 243 |
+
"isVerified": userDataObj.isVerified,
|
| 244 |
+
"isSubscribed": userDataObj.isSubscribed,
|
| 245 |
+
"isBlocked": userDataObj.isBlocked,
|
| 246 |
+
"isDeleted": userDataObj.isDeleted,
|
| 247 |
+
}
|
| 248 |
return JsonResponse(userData, status=200)
|
| 249 |
else:
|
| 250 |
+
# Fallback to regular authentication
|
| 251 |
+
user = authenticate(username=username, password=password)
|
| 252 |
+
if user is not None:
|
| 253 |
+
refresh = RefreshToken.for_user(user)
|
| 254 |
+
userDataObj = UserData.objects.get(user=user)
|
| 255 |
+
userData = {
|
| 256 |
+
'email': user.email,
|
| 257 |
+
'first_name': user.first_name,
|
| 258 |
+
'last_name': user.last_name,
|
| 259 |
+
'access': str(refresh.access_token),
|
| 260 |
+
'refresh': str(refresh),
|
| 261 |
+
"phone": userDataObj.phone,
|
| 262 |
+
"refCode": userDataObj.refCode,
|
| 263 |
+
"birthDate": userDataObj.birthDate,
|
| 264 |
+
"gender": userDataObj.gender,
|
| 265 |
+
"streetName": userDataObj.streetName,
|
| 266 |
+
"city": userDataObj.city,
|
| 267 |
+
"state": userDataObj.state,
|
| 268 |
+
"country": userDataObj.country,
|
| 269 |
+
"pincode": userDataObj.pincode,
|
| 270 |
+
"rewardPoints": userDataObj.rewardPoints,
|
| 271 |
+
"isVerified": userDataObj.isVerified,
|
| 272 |
+
"isSubscribed": userDataObj.isSubscribed,
|
| 273 |
+
"isBlocked": userDataObj.isBlocked,
|
| 274 |
+
"isDeleted": userDataObj.isDeleted,
|
| 275 |
+
}
|
| 276 |
+
return JsonResponse(userData, status=200)
|
| 277 |
+
else:
|
| 278 |
+
return JsonResponse({'error': 'Invalid credentials'}, status=401)
|
| 279 |
except Exception as e:
|
| 280 |
print(e)
|
| 281 |
return JsonResponse({'error': str(e)}, status=400)
|
barcode.png
ADDED
|
dataScript.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* ===================================================================================
|
| 3 |
+
* === Google Maps - Fully Automated Georgia Gas Station Scraper =====================
|
| 4 |
+
* ===================================================================================
|
| 5 |
+
*
|
| 6 |
+
* WARNING: THIS SCRIPT VIOLATES GOOGLE'S TERMS OF SERVICE. USE AT YOUR OWN RISK.
|
| 7 |
+
* IT IS FOR EDUCATIONAL PURPOSES ONLY.
|
| 8 |
+
*
|
| 9 |
+
* This script will automatically:
|
| 10 |
+
* 1. Loop through a list of all 159 counties in Georgia.
|
| 11 |
+
* 2. Skip any counties that have already been scraped and saved.
|
| 12 |
+
* 3. Type the search query into the Google Maps search bar.
|
| 13 |
+
* 4. Click the search button.
|
| 14 |
+
* 5. Wait for results to load.
|
| 15 |
+
* 6. Scrape all business details on the current page.
|
| 16 |
+
* 7. Scroll and click the "Next page" button until all pages are scraped.
|
| 17 |
+
* 8. Save the collected data for the county into localStorage.
|
| 18 |
+
* 9. Move to the next county.
|
| 19 |
+
*
|
| 20 |
+
* ===================================================================================
|
| 21 |
+
*/
|
| 22 |
+
(async () => {
|
| 23 |
+
// --- Configuration & Data ---
|
| 24 |
+
const counties = ["Appling", "Atkinson", "Bacon", "Baker", "Baldwin", "Banks", "Barrow", "Bartow", "Ben Hill", "Berrien", "Bibb", "Bleckley", "Brantley", "Brooks", "Bryan", "Bulloch", "Burke", "Butts", "Calhoun", "Camden", "Candler", "Carroll", "Catoosa", "Charlton", "Chatham", "Chattahoochee", "Chattooga", "Cherokee", "Clarke", "Clay", "Clayton", "Clinch", "Cobb", "Coffee", "Colquitt", "Columbia", "Cook", "Coweta", "Crawford", "Crisp", "Dade", "Dawson", "Decatur", "DeKalb", "Dodge", "Dooly", "Dougherty", "Douglas", "Early", "Echols", "Effingham", "Elbert", "Emanuel", "Evans", "Fannin", "Fayette", "Floyd", "Forsyth", "Franklin", "Fulton", "Gilmer", "Glascock", "Glynn", "Gordon", "Grady", "Greene", "Gwinnett", "Habersham", "Hall", "Hancock", "Haralson", "Harris", "Hart", "Heard", "Henry", "Houston", "Irwin", "Jackson", "Jasper", "Jeff Davis", "Jefferson", "Jenkins", "Johnson", "Jones", "Lamar", "Lanier", "Laurens", "Lee", "Liberty", "Lincoln", "Long", "Lowndes", "Lumpkin", "Macon", "Madison", "Marion", "McDuffie", "McIntosh", "Meriwether", "Miller", "Mitchell", "Monroe", "Montgomery", "Morgan", "Murray", "Muscogee", "Newton", "Oconee", "Oglethorpe", "Paulding", "Peach", "Pickens", "Pierce", "Pike", "Polk", "Pulaski", "Putnam", "Quitman", "Rabun", "Randolph", "Richmond", "Rockdale", "Schley", "Screven", "Seminole", "Spalding", "Stephens", "Stewart", "Sumter", "Talbot", "Taliaferro", "Tattnall", "Taylor", "Telfair", "Terrell", "Thomas", "Tift", "Toombs", "Towns", "Treutlen", "Troup", "Turner", "Twiggs", "Union", "Upson", "Walker", "Walton", "Ware", "Warren", "Washington", "Wayne", "Webster", "Wheeler", "White", "Whitfield", "Wilcox", "Wilkes", "Wilkinson", "Worth"];
|
| 25 |
+
const LOCAL_STORAGE_KEY = "gaGasStationsDB";
|
| 26 |
+
|
| 27 |
+
// --- Helper Functions ---
|
| 28 |
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
| 29 |
+
const randomDelay = (min = 1000, max = 3000) => Math.floor(Math.random() * (max - min + 1) + min);
|
| 30 |
+
|
| 31 |
+
const waitFor = (selector, timeout = 20000) =>
|
| 32 |
+
new Promise((resolve, reject) => {
|
| 33 |
+
const interval = 100;
|
| 34 |
+
let time = 0;
|
| 35 |
+
const timer = setInterval(() => {
|
| 36 |
+
const el = document.querySelector(selector);
|
| 37 |
+
if (el) {
|
| 38 |
+
clearInterval(timer);
|
| 39 |
+
resolve(el);
|
| 40 |
+
}
|
| 41 |
+
time += interval;
|
| 42 |
+
if (time >= timeout) {
|
| 43 |
+
clearInterval(timer);
|
| 44 |
+
reject(new Error(`Timeout waiting for selector: ${selector}`));
|
| 45 |
+
}
|
| 46 |
+
}, interval);
|
| 47 |
+
});
|
| 48 |
+
|
| 49 |
+
// More robust way to set input value for sites using frameworks like React
|
| 50 |
+
function setNativeValue(element, value) {
|
| 51 |
+
const valueSetter = Object.getOwnPropertyDescriptor(element, "value")?.set;
|
| 52 |
+
const prototype = Object.getPrototypeOf(element);
|
| 53 |
+
const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, "value")?.set;
|
| 54 |
+
|
| 55 |
+
if (prototypeValueSetter) {
|
| 56 |
+
prototypeValueSetter.call(element, value);
|
| 57 |
+
} else if (valueSetter) {
|
| 58 |
+
valueSetter.call(element, value);
|
| 59 |
+
} else {
|
| 60 |
+
element.value = value;
|
| 61 |
+
}
|
| 62 |
+
element.dispatchEvent(new Event("input", { bubbles: true }));
|
| 63 |
+
element.dispatchEvent(new Event("change", { bubbles: true }));
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
// --- Main Logic ---
|
| 67 |
+
let db = JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY) || "{}");
|
| 68 |
+
const countiesToDo = counties.filter((c) => !db[c]);
|
| 69 |
+
|
| 70 |
+
if (countiesToDo.length === 0) {
|
| 71 |
+
console.log("🎉 All counties have already been scraped! Data is in localStorage.");
|
| 72 |
+
console.log('To view it, run: JSON.parse(localStorage.getItem("' + LOCAL_STORAGE_KEY + '"))');
|
| 73 |
+
console.log('To restart, run: localStorage.removeItem("' + LOCAL_STORAGE_KEY + '")');
|
| 74 |
+
return;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
console.log(`🚀 Starting scraper. ${counties.length} total counties, ${countiesToDo.length} remaining.`);
|
| 78 |
+
await sleep(2000);
|
| 79 |
+
|
| 80 |
+
for (const county of countiesToDo) {
|
| 81 |
+
console.log(`====================================================`);
|
| 82 |
+
console.log(`🔍 Now processing: ${county} County`);
|
| 83 |
+
|
| 84 |
+
try {
|
| 85 |
+
// 1. Perform Search
|
| 86 |
+
const searchInput = await waitFor("input#searchboxinput");
|
| 87 |
+
const searchButton = await waitFor("button#searchbox-searchbutton");
|
| 88 |
+
const searchQuery = `gas station in ${county} County, Georgia, USA`;
|
| 89 |
+
|
| 90 |
+
console.log(` - Typing search query: "${searchQuery}"`);
|
| 91 |
+
setNativeValue(searchInput, searchQuery);
|
| 92 |
+
await sleep(randomDelay(500, 1000));
|
| 93 |
+
|
| 94 |
+
console.log(` - Clicking search button...`);
|
| 95 |
+
searchButton.click();
|
| 96 |
+
|
| 97 |
+
// 2. Wait for results panel and scrape
|
| 98 |
+
const resultsPanelSelector = `div[aria-label*="Results for gas station in ${county} County"]`;
|
| 99 |
+
const panel = await waitFor(resultsPanelSelector);
|
| 100 |
+
console.log(` - Results panel loaded.`);
|
| 101 |
+
await sleep(randomDelay(3000, 5000)); // Wait for results to populate
|
| 102 |
+
|
| 103 |
+
const stations = [];
|
| 104 |
+
let page = 1;
|
| 105 |
+
let LastLength = 0;
|
| 106 |
+
while (true) {
|
| 107 |
+
console.log(` - Scraping page ${page}...`);
|
| 108 |
+
// Scroll to bottom to ensure all results on the page are rendered
|
| 109 |
+
panel.scrollTop = panel.scrollHeight;
|
| 110 |
+
await sleep(randomDelay(2000, 3500));
|
| 111 |
+
panel.scrollTop = panel.scrollHeight; // scroll again to be sure
|
| 112 |
+
await sleep(1000);
|
| 113 |
+
|
| 114 |
+
// This selector targets the link that wraps each search result item
|
| 115 |
+
const resultItems = document.querySelectorAll('a[href*="https://www.google.com/maps/place/"]');
|
| 116 |
+
console.log(` - Found ${resultItems.length} result items.`);
|
| 117 |
+
if (LastLength === resultItems.length) {
|
| 118 |
+
console.log(` - No new results found.`);
|
| 119 |
+
break;
|
| 120 |
+
}
|
| 121 |
+
LastLength = resultItems.length;
|
| 122 |
+
resultItems.forEach((item) => {
|
| 123 |
+
// Check if this item is actually a result in our list, not a map pin link
|
| 124 |
+
if (!item.closest(resultsPanelSelector)) return;
|
| 125 |
+
const detailsContainer = item.nextElementSibling.nextElementSibling; // Details are often in a sibling div
|
| 126 |
+
if (!stations.some(s => s.url === item.href)) {
|
| 127 |
+
stations.push({ html: detailsContainer.innerHTML, url: item.href });
|
| 128 |
+
}
|
| 129 |
+
});
|
| 130 |
+
|
| 131 |
+
const nextButton = document.querySelector('button[aria-label="Next page"]');
|
| 132 |
+
if (nextButton && !nextButton.disabled) {
|
| 133 |
+
console.log(` - Found ${stations.length} stations so far. Clicking next page...`);
|
| 134 |
+
nextButton.click();
|
| 135 |
+
page++;
|
| 136 |
+
await sleep(randomDelay(4000, 6000)); // Crucial delay for next page to load
|
| 137 |
+
} else {
|
| 138 |
+
console.log(` - No more pages found.`);
|
| 139 |
+
break;
|
| 140 |
+
}
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
// 3. Save Data
|
| 144 |
+
db[county] = stations;
|
| 145 |
+
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(db));
|
| 146 |
+
console.log(`✅ SUCCESS: Saved ${stations.length} stations for ${county} County.`);
|
| 147 |
+
} catch (error) {
|
| 148 |
+
console.error(`❌ ERROR processing ${county} County:`, error.message);
|
| 149 |
+
console.log(` - Skipping this county for now. It will be retried if you run the script again.`);
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
const nextCountyDelay = randomDelay(5000, 10000);
|
| 153 |
+
console.log(` - Waiting for ${Math.round(nextCountyDelay / 1000)} seconds before next county...`);
|
| 154 |
+
await sleep(nextCountyDelay);
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
console.log("🎉🎉🎉 All counties finished! 🎉🎉🎉");
|
| 158 |
+
console.log("To view the final data, run this in the console:");
|
| 159 |
+
console.log(`copy(localStorage.getItem('${LOCAL_STORAGE_KEY}'))`);
|
| 160 |
+
console.log('Then paste the data from your clipboard into a text file and save it as "georgia_gas_stations.json".');
|
| 161 |
+
})();
|
db.sqlite3
CHANGED
|
Binary files a/db.sqlite3 and b/db.sqlite3 differ
|
|
|
demo.svg
ADDED
|
|
locations.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
oneOone/settings.py
CHANGED
|
@@ -32,7 +32,7 @@ CSRF_TRUSTED_ORIGINS = ["http://localhost:8081", "http://192.168.81.1:8000", "ht
|
|
| 32 |
|
| 33 |
# Application definition
|
| 34 |
|
| 35 |
-
INSTALLED_APPS = ["django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "rest_framework", "rest_framework_simplejwt", "rest_framework_simplejwt.token_blacklist", "import_export", "corsheaders", "authentication"
|
| 36 |
|
| 37 |
MIDDLEWARE = [
|
| 38 |
"django.middleware.security.SecurityMiddleware",
|
|
@@ -80,17 +80,17 @@ DATABASES = {
|
|
| 80 |
"OPTIONS": {
|
| 81 |
"gssencmode": "disable",
|
| 82 |
},
|
| 83 |
-
}
|
| 84 |
-
"woocommerce": {
|
| 85 |
-
"ENGINE": "django.db.backends.mysql",
|
| 86 |
-
"NAME": "hvyakryx_wp944",
|
| 87 |
-
"USER": "hvyakryx_appBestBeauty",
|
| 88 |
-
"PASSWORD": "C-H8_VD~jG9a",
|
| 89 |
-
"HOST": "216.137.176.112",
|
| 90 |
-
"PORT": "3306",
|
| 91 |
-
},
|
| 92 |
}
|
| 93 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 94 |
# "default": {
|
| 95 |
# "ENGINE": "django.db.backends.sqlite3",
|
| 96 |
# "NAME": BASE_DIR / "db.sqlite3",
|
|
@@ -132,6 +132,10 @@ USE_TZ = True
|
|
| 132 |
# https://docs.djangoproject.com/en/4.2/howto/static-files/
|
| 133 |
|
| 134 |
STATIC_URL = "static/"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 135 |
|
| 136 |
# Default primary key field type
|
| 137 |
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
|
|
|
|
| 32 |
|
| 33 |
# Application definition
|
| 34 |
|
| 35 |
+
INSTALLED_APPS = ["django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "rest_framework", "rest_framework_simplejwt", "rest_framework_simplejwt.token_blacklist", "import_export", "corsheaders", "authentication"]
|
| 36 |
|
| 37 |
MIDDLEWARE = [
|
| 38 |
"django.middleware.security.SecurityMiddleware",
|
|
|
|
| 80 |
"OPTIONS": {
|
| 81 |
"gssencmode": "disable",
|
| 82 |
},
|
| 83 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
}
|
| 85 |
+
# "woocommerce": {
|
| 86 |
+
# "ENGINE": "django.db.backends.mysql",
|
| 87 |
+
# "NAME": "hvyakryx_wp944",
|
| 88 |
+
# "USER": "hvyakryx_appBestBeauty",
|
| 89 |
+
# "PASSWORD": "C-H8_VD~jG9a",
|
| 90 |
+
# "HOST": "216.137.176.112",
|
| 91 |
+
# "PORT": "3306",
|
| 92 |
+
# },
|
| 93 |
+
|
| 94 |
# "default": {
|
| 95 |
# "ENGINE": "django.db.backends.sqlite3",
|
| 96 |
# "NAME": BASE_DIR / "db.sqlite3",
|
|
|
|
| 132 |
# https://docs.djangoproject.com/en/4.2/howto/static-files/
|
| 133 |
|
| 134 |
STATIC_URL = "static/"
|
| 135 |
+
STATIC_ROOT = BASE_DIR / "staticfiles"
|
| 136 |
+
STATICFILES_DIRS = [BASE_DIR / "static"]
|
| 137 |
+
MEDIA_URL = "media/"
|
| 138 |
+
MEDIA_ROOT = BASE_DIR / "media"
|
| 139 |
|
| 140 |
# Default primary key field type
|
| 141 |
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
|
oneOone/urls.py
CHANGED
|
@@ -1,12 +1,13 @@
|
|
| 1 |
from django.urls import path, include
|
| 2 |
from django.contrib import admin
|
| 3 |
from django.contrib.auth.models import User
|
| 4 |
-
|
|
|
|
| 5 |
|
| 6 |
urlpatterns = [
|
| 7 |
path("admin/", admin.site.urls),
|
| 8 |
path('api-auth/', include('rest_framework.urls')),
|
| 9 |
path('api/auth/', include('authentication.urls')),
|
| 10 |
path('api/', include('api.urls')),
|
| 11 |
-
path('api/wordpress/', include('wordpress_api.urls')),
|
| 12 |
-
]
|
|
|
|
| 1 |
from django.urls import path, include
|
| 2 |
from django.contrib import admin
|
| 3 |
from django.contrib.auth.models import User
|
| 4 |
+
from django.conf import settings
|
| 5 |
+
from django.conf.urls.static import static
|
| 6 |
|
| 7 |
urlpatterns = [
|
| 8 |
path("admin/", admin.site.urls),
|
| 9 |
path('api-auth/', include('rest_framework.urls')),
|
| 10 |
path('api/auth/', include('authentication.urls')),
|
| 11 |
path('api/', include('api.urls')),
|
| 12 |
+
# path('api/wordpress/', include('wordpress_api.urls')),
|
| 13 |
+
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
requirements.txt
CHANGED
|
Binary files a/requirements.txt and b/requirements.txt differ
|
|
|
revelAPI.py
CHANGED
|
@@ -84,3 +84,15 @@ headers = {
|
|
| 84 |
response = requests.request("GET", url, headers=headers, data=payload)
|
| 85 |
|
| 86 |
print(response.text)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
response = requests.request("GET", url, headers=headers, data=payload)
|
| 85 |
|
| 86 |
print(response.text)
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
url = "https://101smokeshop-uat.revelup.com/resources/Customer/2366/?fields="
|
| 90 |
+
|
| 91 |
+
payload = {}
|
| 92 |
+
headers = {
|
| 93 |
+
'API-AUTHENTICATION': 'fab57498544244e38bfc2741880f8d61:ed9628295b0642e1b38308795c9cdadd58012df4ceb84a3b9d441c017a1eeac0'
|
| 94 |
+
}
|
| 95 |
+
response = requests.request("GET", url, headers=headers, data=payload)
|
| 96 |
+
print(response.text)
|
| 97 |
+
|
| 98 |
+
|
rewardsRevelAPI.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import requests
|
| 3 |
+
|
| 4 |
+
headers = {
|
| 5 |
+
'Host': '101smokeshop.revelup.com',
|
| 6 |
+
'Accept': '*/*',
|
| 7 |
+
'X-Use-TZ': 'America/New_York',
|
| 8 |
+
'X-Revel-Revision': '0',
|
| 9 |
+
# 'Accept-Encoding': 'gzip, deflate, br',
|
| 10 |
+
'Accept-Language': 'en-US,en;q=0.9',
|
| 11 |
+
'X-Model-Num': 'iPad (9th Gen)',
|
| 12 |
+
'X-Pos-Establishment': '2',
|
| 13 |
+
'Content-Type': 'application/json',
|
| 14 |
+
'User-Agent': 'POS/0 CFNetwork/3826.500.131 Darwin/24.5.0',
|
| 15 |
+
'Connection': 'keep-alive',
|
| 16 |
+
'X-USE-ESTIMATED-COUNT': 'True',
|
| 17 |
+
'API-AUTHENTICATION': '50d3c325c7794b2e8684cffc4562dfc8:ae2b6a4b97144a8dbdafd6262d3d513e03bac37fae2147f484f3625a8dc144dd',
|
| 18 |
+
'X-Os-Version': 'iOS 18.5',
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
params = {
|
| 22 |
+
'number': '15616355610',
|
| 23 |
+
'format': 'json',
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
response = requests.get('https://101smokeshop.revelup.com/resources/RewardsCard/', params=params, headers=headers, verify=True)
|
| 27 |
+
print(response.json())
|
| 28 |
+
|
| 29 |
+
headers = {
|
| 30 |
+
'Host': '101smokeshop.revelup.com',
|
| 31 |
+
'Accept': '*/*',
|
| 32 |
+
'X-Use-TZ': 'America/New_York',
|
| 33 |
+
'X-Revel-Revision': '0',
|
| 34 |
+
# 'Accept-Encoding': 'gzip, deflate, br',
|
| 35 |
+
'Accept-Language': 'en-US,en;q=0.9',
|
| 36 |
+
'X-Model-Num': 'iPad (9th Gen)',
|
| 37 |
+
'X-Pos-Establishment': '2',
|
| 38 |
+
'Content-Type': 'application/json',
|
| 39 |
+
'User-Agent': 'POS/0 CFNetwork/3826.500.131 Darwin/24.5.0',
|
| 40 |
+
'Connection': 'keep-alive',
|
| 41 |
+
'X-USE-ESTIMATED-COUNT': 'True',
|
| 42 |
+
'API-AUTHENTICATION': '50d3c325c7794b2e8684cffc4562dfc8:ae2b6a4b97144a8dbdafd6262d3d513e03bac37fae2147f484f3625a8dc144dd',
|
| 43 |
+
'X-Os-Version': 'iOS 18.5',
|
| 44 |
+
}
|
| 45 |
+
post_payload = {
|
| 46 |
+
"points_by_items": 50.0,
|
| 47 |
+
"points_by_purchases": 50.0,
|
| 48 |
+
"points_by_visits": 10.0,
|
| 49 |
+
"total_purchases": 100.0,
|
| 50 |
+
"current_points": 100.0,
|
| 51 |
+
"total_points": 100.0,
|
| 52 |
+
"number": "5551231231234",
|
| 53 |
+
"customer": "/resources/Customer/2907/",
|
| 54 |
+
"updated_by": "/enterprise/User/72/",
|
| 55 |
+
'created_by': '/enterprise/User/337/',
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
# post_response = requests.put(
|
| 59 |
+
# 'https://101smokeshop.revelup.com/resources/RewardsCard/2/',
|
| 60 |
+
# headers=headers,
|
| 61 |
+
# data=json.dumps(post_payload),
|
| 62 |
+
# verify=True
|
| 63 |
+
# )
|
| 64 |
+
# print(post_response.text)
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
# url = "https://101smokeshop-uat.revelup.com/resources/RewardsCard/1/"
|
| 68 |
+
# payload = {}
|
| 69 |
+
# headers = {
|
| 70 |
+
# 'API-AUTHENTICATION': 'fab57498544244e38bfc2741880f8d61:ed9628295b0642e1b38308795c9cdadd58012df4ceb84a3b9d441c017a1eeac0'
|
| 71 |
+
# }
|
| 72 |
+
# response = requests.request("GET", url, headers=headers, data=payload)
|
| 73 |
+
# print(response.json())
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
# url = "https://101smokeshop-uat.revelup.com/resources/RewardsCard/1/"
|
| 77 |
+
# payload = {"points_by_items": 500.0, "points_by_purchases": 200.0, "points_by_visits": 100.0, "total_points": 800.0,"current_points": 800.0, "number": "12345"}
|
| 78 |
+
# headers = {"API-AUTHENTICATION": "fab57498544244e38bfc2741880f8d61:ed9628295b0642e1b38308795c9cdadd58012df4ceb84a3b9d441c017a1eeac0", "Content-Type": "application/json"}
|
| 79 |
+
# response = requests.request("PUT", url, headers=headers, data=json.dumps(payload))
|
| 80 |
+
# print(response.text)
|
static/home/1.jpg
ADDED
|
Git LFS Details
|
static/home/1.png
ADDED
|
Git LFS Details
|
static/home/2.jpg
ADDED
|
Git LFS Details
|
static/home/2.png
ADDED
|
Git LFS Details
|
static/home/3.jpg
ADDED
|
Git LFS Details
|
static/home/3.png
ADDED
|
Git LFS Details
|
static/home/4.jpg
ADDED
|
Git LFS Details
|
static/home/4.png
ADDED
|
Git LFS Details
|
static/home/5.jpg
ADDED
|
Git LFS Details
|
static/home/5.png
ADDED
|
Git LFS Details
|