snapshot
This commit is contained in:
+34
-27
@@ -1,12 +1,12 @@
|
||||
import argparse
|
||||
import asyncio
|
||||
import contextlib
|
||||
import dataclasses
|
||||
import datetime
|
||||
import logging
|
||||
import random
|
||||
import re
|
||||
import subprocess
|
||||
import time
|
||||
import urllib.parse
|
||||
from pathlib import Path
|
||||
|
||||
@@ -39,7 +39,16 @@ dump_dir = Path('~/Desktop').expanduser() / 'immigration'
|
||||
dump_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
async def check_slots(page: Page, retry_count: int = 1) -> list[datetime.datetime]:
|
||||
@dataclasses.dataclass
|
||||
class ResidencyApplication:
|
||||
citizenship_country: str
|
||||
num_applicants: int
|
||||
is_living_with_family: bool
|
||||
residency_category: str
|
||||
residency_purpose: str
|
||||
|
||||
|
||||
async def check_slots(page: Page, values: ResidencyApplication, retry_count: int = 1) -> list[datetime.datetime]:
|
||||
await page.add_init_script('''Object.defineProperty(navigator, 'webdriver', { get: () => false })''')
|
||||
window_id = random.randint(1000, 9999)
|
||||
req_id = random.randint(0, 999)
|
||||
@@ -47,45 +56,37 @@ async def check_slots(page: Page, retry_count: int = 1) -> list[datetime.datetim
|
||||
f'https://otv.verwalt-berlin.de/ams/TerminBuchen/wizardng?dswid={window_id}&dsrid={req_id}',
|
||||
wait_until='networkidle',
|
||||
)
|
||||
|
||||
async with page.expect_navigation():
|
||||
await page.click('.langBlock [name="txtEn"] a')
|
||||
|
||||
await page.check('[name="gelesen"]')
|
||||
async with page.expect_navigation(url=re.compile('st=2')):
|
||||
|
||||
async with page.expect_navigation(url=re.compile('st=2'), wait_until='networkidle'):
|
||||
await page.click('[name="applicationForm:managedForm:proceed"]')
|
||||
|
||||
await page.get_by_role("combobox", name="Staatsangehörigkeit *").select_option(label="Türkei")
|
||||
await page.get_by_role("combobox", name="Citizenship *").select_option(label=values.citizenship_country)
|
||||
await asyncio.sleep(0.3)
|
||||
|
||||
await page.get_by_role(
|
||||
"combobox",
|
||||
name="Anzahl der Personen, die einen Aufenthaltstitel beantragen (auch ausländische Ehepartner und Kinder) *",
|
||||
).select_option(label="eine Person")
|
||||
# how many applicants
|
||||
await page.select_option('[name="personenAnzahl_normal"]', value=str(values.num_applicants))
|
||||
await asyncio.sleep(0.3)
|
||||
|
||||
await page.get_by_role(
|
||||
"combobox", name="Leben Sie in Berlin zusammen mit einem Familienangehörigen (z.B. Ehepartner, Kind) *"
|
||||
).select_option(label="nein")
|
||||
# living with family
|
||||
await page.select_option('[name="lebnBrMitFmly"]', value='1' if values.is_living_with_family else '2')
|
||||
await asyncio.sleep(0.3)
|
||||
|
||||
await page.get_by_text("Aufenthaltstitel - beantragen").click()
|
||||
await page.locator("label").filter(has_text="Erwerbstätigkeit").click()
|
||||
await page.get_by_text("Blaue Karte EU (§ 18b Abs. 2)").click()
|
||||
await page.get_by_text("Apply for a residence title").click()
|
||||
await page.locator("label").filter(has_text=values.residency_category).click()
|
||||
await page.get_by_text(values.residency_purpose).click()
|
||||
|
||||
stop_at = datetime.datetime.now() + datetime.timedelta(minutes=28)
|
||||
|
||||
async def go_forward():
|
||||
async with page.expect_navigation(url=re.compile(r'st='), wait_until='networkidle', timeout=60_000):
|
||||
await page.get_by_role("button", name="Weiter").click()
|
||||
if 'st=2' in page.url:
|
||||
error_message = await page.inner_text('.errorMessage')
|
||||
if 'keine Termine frei' in error_message:
|
||||
return False
|
||||
raise Error(error_message)
|
||||
return 'st=3' in page.url
|
||||
|
||||
while 'st=2' in page.url:
|
||||
retry_count -= 1
|
||||
|
||||
async with page.expect_navigation(url=re.compile(r'st='), wait_until='networkidle', timeout=60_000):
|
||||
await page.get_by_role("button", name="Weiter").click()
|
||||
await page.get_by_role("button", name="Next").click()
|
||||
|
||||
if datetime.datetime.now() > stop_at:
|
||||
raise TimeoutError('could not find a slot')
|
||||
@@ -134,7 +135,14 @@ async def main():
|
||||
args = parse_args()
|
||||
async with launch_browser(headless=args.headless) as page:
|
||||
try:
|
||||
slots = await check_slots(page, retry_count=args.retry_count)
|
||||
values = ResidencyApplication(
|
||||
citizenship_country='India',
|
||||
num_applicants=1,
|
||||
is_living_with_family=False,
|
||||
residency_category='Educational purposes',
|
||||
residency_purpose='Residence permit for the purpose of studying (sect. 16b)',
|
||||
)
|
||||
slots = await check_slots(page, values=values, retry_count=args.retry_count)
|
||||
if not slots:
|
||||
print('no slots yet')
|
||||
return
|
||||
@@ -146,4 +154,3 @@ async def main():
|
||||
if __name__ == '__main__':
|
||||
asyncio.run(main())
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user