nopoh22 commited on
Commit
8343fc0
·
verified ·
1 Parent(s): 0fd0e5c

Update renewer.py

Browse files
Files changed (1) hide show
  1. renewer.py +67 -52
renewer.py CHANGED
@@ -27,7 +27,6 @@ def save_accounts(accounts):
27
 
28
 
29
  def get_host(username, token):
30
- """اكتشاف الخادم (US أو EU) عبر الـ Token"""
31
  for host in ["www.pythonanywhere.com", "eu.pythonanywhere.com"]:
32
  try:
33
  r = requests.get(
@@ -43,61 +42,81 @@ def get_host(username, token):
43
 
44
 
45
  def extend_webapp(username, password, host="www.pythonanywhere.com"):
46
- """
47
- التمديد الحقيقي عبر session + CSRF
48
- يضغط زر Extend تماماً كما لو فعلته يدوياً
49
- """
50
  session = requests.Session()
51
  results = []
52
 
 
 
 
 
 
 
 
53
  try:
54
- # ── الخطوة 1: فتح صفحة تسجيل الدخول وجلب CSRF ──
55
  login_url = f"https://{host}/login/"
56
  login_page = session.get(login_url, timeout=15)
57
  logger.info(f"[{username}] صفحة الدخول: {login_page.status_code}")
58
 
59
  soup = BeautifulSoup(login_page.text, "html.parser")
60
- csrf_input = soup.find("input", {"name": "csrfmiddlewaretoken"})
61
- if not csrf_input:
62
- logger.error(f"[{username}] لم يتم العثور على CSRF في صفحة تسجيل الدخول")
 
 
63
  return []
64
- csrf = csrf_input["value"]
65
- logger.info(f"[{username}] CSRF الأول: {csrf[:10]}...")
66
-
67
- # ── الخطوة 2: تسجيل الدخول ──
68
- login_data = {
69
- "auth-username": username,
70
- "auth-password": password,
71
- "csrfmiddlewaretoken": csrf,
72
- "next": "/"
73
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  login_resp = session.post(
75
- login_url,
76
- data=login_data,
77
  headers={
78
  "Referer": login_url,
79
- "Content-Type": "application/x-www-form-urlencoded"
 
80
  },
81
  timeout=15,
82
  allow_redirects=True
83
  )
84
- logger.info(f"[{username}] نتيجة تسجيل الدخول: {login_resp.status_code} | URL: {login_resp.url}")
85
 
86
  # ── التحقق من نجاح تسجيل الدخول ──
87
- # الطريقة الصحيحة: نتحقق أن URL النهائي ليس صفحة login
88
- final_url = login_resp.url
89
- if "login" in final_url.lower():
90
- logger.error(f"[{username}] فشل تسجيل الدخول — ما زال على صفحة login")
91
- return []
92
-
93
- # تحقق إضافي: هل يوجد sessionid في الـ cookies؟
94
  cookies = session.cookies.get_dict()
95
  logger.info(f"[{username}] الكوكيز: {list(cookies.keys())}")
 
96
  if "sessionid" not in cookies:
97
- logger.error(f"[{username}] لم يتم إنشاء session — فشل تسجيل الدخول")
98
  return []
99
 
100
- logger.info(f"[{username}] ✅ تم تسجيل الدخول بنجاح على {host}")
 
 
 
 
101
 
102
  # ── الخطوة 3: فتح صفحة الويب آب وجلب CSRF جديد ──
103
  webapps_url = f"https://{host}/user/{username}/webapps/"
@@ -107,18 +126,17 @@ def extend_webapp(username, password, host="www.pythonanywhere.com"):
107
  soup = BeautifulSoup(page.text, "html.parser")
108
  csrf_input = soup.find("input", {"name": "csrfmiddlewaretoken"})
109
  if not csrf_input:
110
- # محاولة بديلة من الـ meta tag
111
  meta = soup.find("meta", {"name": "csrf-token"})
112
- if meta:
113
- csrf = meta.get("content", "")
114
- else:
115
- logger.error(f"[{username}] لم يتم العثور على CSRF في صفحة الويب آب")
116
- return []
117
  else:
118
  csrf = csrf_input["value"]
119
- logger.info(f"[{username}] CSRF الثاني: {csrf[:10]}...")
120
 
121
- # ── الخطوة 4: اكتشاف النطاقات المتاحة ──
 
 
 
 
 
122
  domains = []
123
  for link in soup.find_all("a", href=True):
124
  href = link["href"]
@@ -129,11 +147,11 @@ def extend_webapp(username, password, host="www.pythonanywhere.com"):
129
 
130
  if not domains:
131
  domains = [f"{username}.pythonanywhere.com"]
132
- logger.warning(f"[{username}] لم يتم اكتشاف نطاقات، سيجرب: {domains[0]}")
133
  else:
134
- logger.info(f"[{username}] النطاقات المكتشفة: {domains}")
135
 
136
- # ── الخطوة 5: إرسال طلب التمديد لكل نطاق ──
137
  for domain in domains:
138
  extend_url = f"https://{host}/user/{username}/webapps/{domain}/extend"
139
  resp = session.post(
@@ -141,21 +159,18 @@ def extend_webapp(username, password, host="www.pythonanywhere.com"):
141
  data={"csrfmiddlewaretoken": csrf},
142
  headers={
143
  "Referer": webapps_url,
144
- "Content-Type": "application/x-www-form-urlencoded"
 
145
  },
146
  timeout=15
147
  )
148
  logger.info(f"[{username}] Extend {domain}: HTTP {resp.status_code}")
149
 
150
- if resp.status_code in (200, 302):
151
- status = "✅ تم التمديد"
152
- else:
153
- status = f"❌ فشل ({resp.status_code})"
154
-
155
  results.append({"domain": domain, "status": status})
156
 
157
  except Exception as e:
158
- logger.error(f"[{username}] خطأ أثناء التمديد: {e}")
159
 
160
  return results
161
 
@@ -166,7 +181,7 @@ def renew_account(account):
166
  host = account.get("host", "www.pythonanywhere.com")
167
 
168
  if not password:
169
- logger.error(f"[{username}] لا توجد كلمة مرور — لا يمكن التمديد")
170
  return False, []
171
 
172
  results = extend_webapp(username, password, host)
@@ -197,7 +212,7 @@ def run_renewals():
197
  next_renewal = datetime.fromisoformat(next_renewal_str)
198
  if now < next_renewal:
199
  remaining = (next_renewal - now).days
200
- logger.info(f"[{username}] لا حاجة للتجديد — بعد {remaining} يوم")
201
  continue
202
 
203
  logger.info(f"[{username}] جاري التمديد...")
 
27
 
28
 
29
  def get_host(username, token):
 
30
  for host in ["www.pythonanywhere.com", "eu.pythonanywhere.com"]:
31
  try:
32
  r = requests.get(
 
42
 
43
 
44
  def extend_webapp(username, password, host="www.pythonanywhere.com"):
 
 
 
 
45
  session = requests.Session()
46
  results = []
47
 
48
+ # headers تحاكي المتصفح تماماً
49
+ session.headers.update({
50
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
51
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
52
+ "Accept-Language": "en-US,en;q=0.9",
53
+ })
54
+
55
  try:
56
+ # ── الخطوة 1: فتح صفحة تسجيل الدخول ──
57
  login_url = f"https://{host}/login/"
58
  login_page = session.get(login_url, timeout=15)
59
  logger.info(f"[{username}] صفحة الدخول: {login_page.status_code}")
60
 
61
  soup = BeautifulSoup(login_page.text, "html.parser")
62
+
63
+ # اجلب كل حقول الـ form تلقائياً
64
+ form = soup.find("form")
65
+ if not form:
66
+ logger.error(f"[{username}] لم يتم العثور على form في صفحة الدخول")
67
  return []
68
+
69
+ # ابدأ بكل الحقول الموجودة في الـ form (hidden fields)
70
+ form_data = {}
71
+ for inp in form.find_all("input"):
72
+ name = inp.get("name")
73
+ value = inp.get("value", "")
74
+ if name:
75
+ form_data[name] = value
76
+
77
+ logger.info(f"[{username}] حقول الـ form: {list(form_data.keys())}")
78
+
79
+ # أضف بيانات الدخول
80
+ form_data["auth-username"] = username
81
+ form_data["auth-password"] = password
82
+
83
+ # بعض إصدارات الموقع تحتاج هذا الحقل
84
+ if "login_view-current_step" not in form_data:
85
+ form_data["login_view-current_step"] = "auth"
86
+
87
+ # ── الخطوة 2: إرسال بيانات الدخول ──
88
+ form_action = form.get("action") or login_url
89
+ if not form_action.startswith("http"):
90
+ form_action = f"https://{host}{form_action}"
91
+
92
+ logger.info(f"[{username}] إرسال الدخول إلى: {form_action}")
93
+
94
  login_resp = session.post(
95
+ form_action,
96
+ data=form_data,
97
  headers={
98
  "Referer": login_url,
99
+ "Content-Type": "application/x-www-form-urlencoded",
100
+ "Origin": f"https://{host}",
101
  },
102
  timeout=15,
103
  allow_redirects=True
104
  )
105
+ logger.info(f"[{username}] نتيجة الدخول: {login_resp.status_code} | URL: {login_resp.url}")
106
 
107
  # ── التحقق من نجاح تسجيل الدخول ──
 
 
 
 
 
 
 
108
  cookies = session.cookies.get_dict()
109
  logger.info(f"[{username}] الكوكيز: {list(cookies.keys())}")
110
+
111
  if "sessionid" not in cookies:
112
+ logger.error(f"[{username}] لم يتم إنشاء sessionid — فشل تسجيل الدخول")
113
  return []
114
 
115
+ if "login" in login_resp.url.lower() and login_resp.status_code != 200:
116
+ logger.error(f"[{username}] ما زال على صفحة login — فشل")
117
+ return []
118
+
119
+ logger.info(f"[{username}] ✅ تم تسجيل الدخول بنجاح")
120
 
121
  # ── الخطوة 3: فتح صفحة الويب آب وجلب CSRF جديد ──
122
  webapps_url = f"https://{host}/user/{username}/webapps/"
 
126
  soup = BeautifulSoup(page.text, "html.parser")
127
  csrf_input = soup.find("input", {"name": "csrfmiddlewaretoken"})
128
  if not csrf_input:
 
129
  meta = soup.find("meta", {"name": "csrf-token"})
130
+ csrf = meta.get("content", "") if meta else ""
 
 
 
 
131
  else:
132
  csrf = csrf_input["value"]
 
133
 
134
+ if not csrf:
135
+ logger.error(f"[{username}] لم يتم العثور على CSRF في صفحة الويب آب")
136
+ return []
137
+ logger.info(f"[{username}] CSRF الويب آب: {csrf[:10]}...")
138
+
139
+ # ── الخطوة 4: اكتشاف النطاقات ──
140
  domains = []
141
  for link in soup.find_all("a", href=True):
142
  href = link["href"]
 
147
 
148
  if not domains:
149
  domains = [f"{username}.pythonanywhere.com"]
150
+ logger.warning(f"[{username}] النطاق الافتراضي: {domains[0]}")
151
  else:
152
+ logger.info(f"[{username}] النطاقات: {domains}")
153
 
154
+ # ── الخطوة 5: إرسال طلب التمديد ──
155
  for domain in domains:
156
  extend_url = f"https://{host}/user/{username}/webapps/{domain}/extend"
157
  resp = session.post(
 
159
  data={"csrfmiddlewaretoken": csrf},
160
  headers={
161
  "Referer": webapps_url,
162
+ "Content-Type": "application/x-www-form-urlencoded",
163
+ "Origin": f"https://{host}",
164
  },
165
  timeout=15
166
  )
167
  logger.info(f"[{username}] Extend {domain}: HTTP {resp.status_code}")
168
 
169
+ status = "✅ تم التمديد" if resp.status_code in (200, 302) else f"❌ فشل ({resp.status_code})"
 
 
 
 
170
  results.append({"domain": domain, "status": status})
171
 
172
  except Exception as e:
173
+ logger.error(f"[{username}] خطأ: {e}")
174
 
175
  return results
176
 
 
181
  host = account.get("host", "www.pythonanywhere.com")
182
 
183
  if not password:
184
+ logger.error(f"[{username}] لا توجد كلمة مرور")
185
  return False, []
186
 
187
  results = extend_webapp(username, password, host)
 
212
  next_renewal = datetime.fromisoformat(next_renewal_str)
213
  if now < next_renewal:
214
  remaining = (next_renewal - now).days
215
+ logger.info(f"[{username}] التجديد بعد {remaining} يوم")
216
  continue
217
 
218
  logger.info(f"[{username}] جاري التمديد...")