-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.py
More file actions
125 lines (104 loc) · 4.8 KB
/
Copy pathconfig.py
File metadata and controls
125 lines (104 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import aiohttp
import asyncio
from datetime import datetime
from dotenv import load_dotenv
import os
import loguru
import random
load_dotenv()
DATABASE_NAME = "data.db"
APP_VERSION = "25.4.1" # Najnowsza wersja Vinted
ACCEPT_LANG = "pl-PL"
DEVICE_MODEL = "SM-G991B" # Samsung Galaxy S21
VINTED_API_BASE = "https://www.vinted.pl"
PROXY_USERNAME = os.getenv("PROXY_USERNAME", "your_username")
PROXY_PASSWORD = os.getenv("PROXY_PASSWORD", "your_password")
PROXY_DOMAIN = "p.webshare.io"
PROXY_PORT = "80"
PROXY_URL = f"http://{PROXY_USERNAME}:{PROXY_PASSWORD}@{PROXY_DOMAIN}:{PROXY_PORT}"
ROTATING_PROXY = f"http://{PROXY_USERNAME}:{PROXY_PASSWORD}@{PROXY_DOMAIN}:{PROXY_PORT}"
session = {}
USER_AGENTS = [
"Mozilla/5.0 (Linux; Android 12; SM-G991B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.129 Mobile Safari/537.36",
"Mozilla/5.0 (Linux; Android 13; SM-S901B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.6167.90 Mobile Safari/537.36",
"Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6099.62 Mobile Safari/537.36",
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Mobile/15E148 Safari/604.1",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
]
ALLOWED_VINTED_DOMAINS = [
"vinted.cz", "www.vinted.cz", # Czech Republic
"vinted.dk", "www.vinted.dk", # Denmark
"vinted.fi", "www.vinted.fi", # Finland
"vinted.hr", "www.vinted.hr", # Croatia
"vinted.lt", "www.vinted.lt", # Lithuania
"vinted.ro", "www.vinted.ro", # Romania
"vinted.se", "www.vinted.se", # Sweden
"vinted.sk", "www.vinted.sk", # Slovakia
"vinted.pl", "www.vinted.pl", # Poland
]
token_refresh_lock = asyncio.Lock()
def get_proxy():
"""Returns the rotating proxy endpoint."""
return {"http": ROTATING_PROXY, "https": ROTATING_PROXY}
async def refresh_oauth_token():
global session
async with token_refresh_lock: # Ensures only one refresh runs at a time
if not session or "expiration_date" not in session or session["expiration_date"] - 60 < datetime.now().timestamp():
loguru.logger.info("🔄 Refreshing OAuth Token before expiration...")
session = await get_oauth_token()
def get_dynamic_headers():
user_agent = random.choice(USER_AGENTS)
return {
"User-Agent": user_agent,
"Accept": "application/json",
"Referer": f"https://www.vinted.pl/",
"x-app-version": APP_VERSION,
"x-device-model": DEVICE_MODEL,
"short-bundle-version": APP_VERSION,
"Accept-Language": "pl-PL",
"Origin": f"https://www.vinted.pl",
"Connection": "keep-alive",
}
async def get_oauth_token():
"""Fetches or refreshes OAuth token for the Vinted API."""
global session
user_agent = random.choice(USER_AGENTS)
payload = {
"grant_type": "password",
"client_id": "android",
"scope": "public"
}
if session and "refresh_token" in session:
payload["grant_type"] = "refresh_token"
payload["refresh_token"] = session["refresh_token"]
async with aiohttp.ClientSession() as client:
async with client.post(
url=f"{VINTED_API_BASE}/oauth/token",
headers={"User-Agent": user_agent, "Accept-Language": ACCEPT_LANG},
json=payload,
) as response:
loguru.logger.info(f"🔍 OAuth Token Request Sent to: {VINTED_API_BASE}/oauth/token")
loguru.logger.info(f"🔹 Payload: {payload}")
if response.status != 200:
text = await response.text()
loguru.logger.error(f"❌ OAuth token request failed: {response.status}")
loguru.logger.error(f"🔹 Response Content: {text}")
await asyncio.sleep(5)
return await get_oauth_token()
content = await response.json()
session = {
"access_token": content["access_token"],
"refresh_token": content["refresh_token"],
"expiration_date": content["created_at"] + content["expires_in"],
}
expiration_time = datetime.fromtimestamp(session["expiration_date"])
loguru.logger.info(f"✅ New OAuth token obtained. Expires at: {expiration_time}")
return session
async def get_headers():
global session
if not session or "expiration_date" not in session or session["expiration_date"] < datetime.now().timestamp():
await refresh_oauth_token()
headers = get_dynamic_headers()
headers["Authorization"] = f"Bearer {session['access_token']}"
return headers