mirror of https://github.com/janLo/punkow
Remove multi booking in one go
This never worked because the service requires a fresh session per booking.
This commit is contained in:
parent
058c410567
commit
9d91371b55
|
|
@ -35,7 +35,7 @@ if __name__ == "__main__":
|
||||||
logger.info("Try to get an appointment at %s", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
|
logger.info("Try to get an appointment at %s", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
|
||||||
data = BookingData(name=args.name, email=args.email)
|
data = BookingData(name=args.name, email=args.email)
|
||||||
svc = BookingService(url, debug=False)
|
svc = BookingService(url, debug=False)
|
||||||
for booked in svc.book([data]):
|
for booked in svc.book(data):
|
||||||
if data == booked:
|
if data == booked:
|
||||||
break
|
break
|
||||||
time.sleep(max(30, args.interval))
|
time.sleep(max(30, args.interval))
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,14 @@ class BookingData(typing.NamedTuple):
|
||||||
id: typing.Optional[int]
|
id: typing.Optional[int]
|
||||||
|
|
||||||
|
|
||||||
|
class BookingResult(typing.NamedTuple):
|
||||||
|
name: str
|
||||||
|
email: str
|
||||||
|
process_id: str
|
||||||
|
auth_key: str
|
||||||
|
metadata: typing.Dict[str, str]
|
||||||
|
|
||||||
|
|
||||||
class BookingService(object):
|
class BookingService(object):
|
||||||
def __init__(self, start_url, debug=True, hide_sensitive_data=False):
|
def __init__(self, start_url, debug=True, hide_sensitive_data=False):
|
||||||
self.session = None
|
self.session = None
|
||||||
|
|
@ -53,8 +61,6 @@ class BookingService(object):
|
||||||
self.session.headers.update({'Referrer': old_referrer})
|
self.session.headers.update({'Referrer': old_referrer})
|
||||||
|
|
||||||
def _print_details(self, zms, depth):
|
def _print_details(self, zms, depth):
|
||||||
if self.sensitive:
|
|
||||||
depth = min(depth, 3)
|
|
||||||
meta = {}
|
meta = {}
|
||||||
groups = zms.find_all("div", "collapsible-toggle")
|
groups = zms.find_all("div", "collapsible-toggle")
|
||||||
for group in groups[:depth]:
|
for group in groups[:depth]:
|
||||||
|
|
@ -71,7 +77,9 @@ class BookingService(object):
|
||||||
title = title.text.strip()
|
title = title.text.strip()
|
||||||
desc = next(desc.stripped_strings)
|
desc = next(desc.stripped_strings)
|
||||||
|
|
||||||
logging.debug(" %s: %s", title, desc)
|
if not self.sensitive:
|
||||||
|
logging.debug(" %s: %s", title, desc)
|
||||||
|
|
||||||
meta[title] = desc
|
meta[title] = desc
|
||||||
|
|
||||||
return meta
|
return meta
|
||||||
|
|
@ -159,7 +167,7 @@ class BookingService(object):
|
||||||
zms = html.find("div", {"class": "zms"})
|
zms = html.find("div", {"class": "zms"})
|
||||||
|
|
||||||
logger.debug("Loaded booking form:")
|
logger.debug("Loaded booking form:")
|
||||||
self._print_details(zms, 4)
|
details = self._print_details(zms, 4)
|
||||||
|
|
||||||
formdata = {"familyName": name, "email": email, "form_validate": "1", "agbgelesen": "1"}
|
formdata = {"familyName": name, "email": email, "form_validate": "1", "agbgelesen": "1"}
|
||||||
process = zms.find("input", {"id": "process"})
|
process = zms.find("input", {"id": "process"})
|
||||||
|
|
@ -204,20 +212,12 @@ class BookingService(object):
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def book(self, data: typing.List[BookingData]):
|
def book(self, data: BookingData):
|
||||||
logging.info("Look for appointments at %s", BASE_URL + self.start_url)
|
logging.info("Look for appointments at %s", BASE_URL + self.start_url)
|
||||||
|
|
||||||
data_iter = iter(data)
|
|
||||||
cur_data = next(data_iter, None)
|
|
||||||
if cur_data is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
for day_url in self._iter_bookable_day_urls(self.start_url):
|
for day_url in self._iter_bookable_day_urls(self.start_url):
|
||||||
with self._local_referrer():
|
with self._local_referrer():
|
||||||
for slot_url in self._iter_bookable_times(day_url):
|
for slot_url in self._iter_bookable_times(day_url):
|
||||||
if self._book_appointment(slot_url, cur_data.name, cur_data.email):
|
if self._book_appointment(slot_url, data.name, data.email):
|
||||||
yield cur_data
|
yield data
|
||||||
cur_data = next(data_iter, None)
|
|
||||||
if cur_data is None:
|
|
||||||
return
|
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ class _WorkerRequest(typing.NamedTuple):
|
||||||
|
|
||||||
class RequestQueue(object):
|
class RequestQueue(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._targets = []
|
self._targets = [] # type: typing.List[str]
|
||||||
self._requests = []
|
self._requests = [] # type: typing.List[_WorkerRequest]
|
||||||
|
|
||||||
def enqueue(self, req: model.Request):
|
def enqueue(self, req: model.Request):
|
||||||
if req.target not in self._requests:
|
if req.target not in self._requests:
|
||||||
|
|
@ -33,9 +33,9 @@ class RequestQueue(object):
|
||||||
self._requests.append(
|
self._requests.append(
|
||||||
_WorkerRequest(req.id, req.data.name, req.data.email, req.target))
|
_WorkerRequest(req.id, req.data.name, req.data.email, req.target))
|
||||||
|
|
||||||
def iterate(self):
|
def iterate(self) -> typing.Generator[_WorkerRequest, None, None]:
|
||||||
for item in self._requests:
|
for item in self._requests:
|
||||||
yield item.target, [item]
|
yield item
|
||||||
|
|
||||||
def is_empty(self):
|
def is_empty(self):
|
||||||
return len(self._targets) == 0
|
return len(self._targets) == 0
|
||||||
|
|
@ -49,13 +49,13 @@ class RequestQueue(object):
|
||||||
return len(self._requests)
|
return len(self._requests)
|
||||||
|
|
||||||
|
|
||||||
def _book(target: str, reqs: typing.List[_WorkerRequest], debug=False) -> typing.List[int]:
|
def _book(req: _WorkerRequest, debug=False) -> typing.List[int]:
|
||||||
data = [scraper.BookingData(name=req.name, email=req.email, id=req.id)
|
data = scraper.BookingData(name=req.name, email=req.email, id=req.id)
|
||||||
for req in reqs]
|
target = req.target
|
||||||
if target.startswith(scraper.BASE_URL):
|
if req.target.startswith(scraper.BASE_URL):
|
||||||
target = target[len(scraper.BASE_URL):]
|
target = req.target[len(scraper.BASE_URL):]
|
||||||
|
|
||||||
logger.debug("Try to book %d appointments for %s", len(reqs), target)
|
logger.debug("Try to book one appointment for %s", target)
|
||||||
|
|
||||||
booked_ids = []
|
booked_ids = []
|
||||||
try:
|
try:
|
||||||
|
|
@ -140,10 +140,10 @@ class Worker(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
booked = []
|
booked = []
|
||||||
for target, reqs in requests.iterate():
|
for req in requests.iterate():
|
||||||
booked.extend(
|
booked.extend(
|
||||||
await self._loop.run_in_executor(self._executor,
|
await self._loop.run_in_executor(self._executor,
|
||||||
functools.partial(_book, target, reqs, debug=self._debug)))
|
functools.partial(_book, req, debug=self._debug)))
|
||||||
|
|
||||||
await self._loop.run_in_executor(None, functools.partial(self.cleanup_booked, booked))
|
await self._loop.run_in_executor(None, functools.partial(self.cleanup_booked, booked))
|
||||||
await self._loop.run_in_executor(None, self.cleanup_old)
|
await self._loop.run_in_executor(None, self.cleanup_old)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue