Ejemplo n.º 1
0
 def __init__(self,
              phone_number: str,
              session_pickle_filename: str,
              load_session: bool = False,
              debug: bool = False) -> None:
     logger.log("info", "Instantiating Notifier...")
     self.phone_number = phone_number
     self.session_pickle_filename = session_pickle_filename
     self.debug = debug
     if load_session:
         self.session = self.load_session()
     else:
         self.session = requests.Session()
     self.headers = {
         'User-Agent':
         'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
         'Chrome/80.0.3987.163 Safari/537.36',
         'X-Channel':
         'BB-WEB',
         'Content-Type':
         'application/json',
         'Accept':
         'application/json',
         'X-Caller':
         'DVAR-SVC',
         'Sec-Fetch-Dest':
         'empty',
         'Referer':
         self.BASE_URL
     }
Ejemplo n.º 2
0
 def visit_cart_page_and_get_address_id(self) -> str:
     logger.log("info", "Visiting cart page...")
     resp = self.session.get(self.BASE_URL + self.CART_ENDPOINT,
                             headers=self.headers)
     addr_id = self._find_address_id(resp.text)
     logger.log("info", "Address Id found")
     return addr_id
Ejemplo n.º 3
0
 def visit_main_page(self) -> Response:
     logger.log("info", "Visiting main website...")
     resp = self.session.get(self.BASE_URL, headers=self.headers)
     if not resp.ok:
         logger.log("error", "Main page not reachable...")
         return resp
     self.headers['X-CSRFToken'] = resp.cookies.get('csrftoken')
     return resp
Ejemplo n.º 4
0
 def wrapper(*args, **kwargs):
     try:
         return job_func(*args, **kwargs)
     except:
         import traceback
         logger.log("critical", traceback.format_exc())
         if cancel_on_failure:
             logger.log("warning", "Job Cancelled due to an error.")
             return schedule.CancelJob
Ejemplo n.º 5
0
 def visit_extra_delivery_slot_check(self) -> bool:
     logger.log("info", "Visiting extra delivery slot check...")
     resp = self.session.get(self.BASE_URL + self.EXTRA_CHECK_ENDPOINT, headers=self.headers)
     if not resp.ok:
         return False
     data = resp.json()
     if 'details' in data and 'checkout_slot_failure_message' in data['details'] and "unfortunately" in data['details']['checkout_slot_failure_message'].lower():
         return False
     return True
Ejemplo n.º 6
0
 def send_otp(self) -> Response:
     logger.log("info", "Sending OTP to {}...".format(self.phone_number))
     resp = self.session.post(self.BASE_URL + self.OTP_ENDPOINT,
                              headers=self.headers,
                              data=json.dumps(
                                  {"identifier": self.phone_number}))
     if not resp.ok:
         logger.log("error", "Failed to send OTP.")
     return resp
Ejemplo n.º 7
0
 def login(self, otp: str) -> Response:
     logger.log("info", "Logging with OTP: {}...".format(otp))
     resp = self.session.post(self.BASE_URL + self.LOGIN_ENDPOINT, headers=self.headers, data=json.dumps(
         {
             "mobile_no": self.phone_number,
             "mobile_no_otp": otp
         }
     ))
     if not resp.ok:
         logger.log("error", "Login failed.")
     return resp
 def wrapper(*args, **kwargs):
     try:
         return job_func(*args, **kwargs)
     except IndexError:
         logger.log(
             "critical",
             "Need to run login.py script since session is either outdated or never created."
         )
     except ConnectionError:
         logger.log("critical", "BigBasket didn't respond well.")
     except:
         logger.log("critical", traceback.format_exc())
         logger.log(
             "critical", "Please report the developer at "
             "https://github.com/wrap-away/bigbasket-notifier/issues "
             "to inform him about this error.")
     if cancel_on_failure:
         logger.log("warning", "Job Cancelled due to an error.")
         return schedule.CancelJob
Ejemplo n.º 9
0
def job(notifier: Notifier, delay: int, system_notifier, telegram_notifier):
    """
    Job to check if a delivery slot gets available for the default selected address in your bigbasket website.
    @param notifier: Notifier - Notifier class - To monitor bigbasket website.
    @param system_notifier: None/notification class - To notify users (cross-platform) via balloon tiles.
    @param delay: int - Just a preventive measure to not make too many requests at the same time.
    @param telegram_notifier: None/Bot class - Telegram integration to notify via bot.
    """
    notifier.visit_main_page()
    time.sleep(delay)
    addr_id = notifier.visit_cart_page_and_get_address_id()
    time.sleep(delay)
    initial_status, resp = notifier.check_if_delivery_slot_available(addr_id)
    if not initial_status:
        return None
    logger.log("warning", "Maybe a delivery slot is found.")
    time.sleep(delay)
    status = notifier.visit_extra_delivery_slot_check()
    if not status:
        logger.log("warning", "No delivery slot was found.")
        return None
    success_message = "A free delivery slot is found for your address!"
    logger.log("critical", success_message)
    if system_notifier:
        system_notifier.notify(title='BigBasket Notifier',
                               message=success_message,
                               app_name='bigbasket-notifier')
    if telegram_notifier:
        telegram_notifier.notify(
            config.get_configuration('chat_id', "TELEGRAM"), success_message)
    return None
Ejemplo n.º 10
0
 def check_if_delivery_slot_available(self,
                                      addr_id: str) -> (bool, Response):
     logger.log("info",
                "Checking delivery slot for addr_id: {}".format(addr_id))
     payload = 'addr_id=' + addr_id
     separate_headers = {
         'Accept':
         'application/json, text/javascript, */*; q=0.01',
         'Sec-Fetch-Dest':
         'empty',
         'X-CSRFToken':
         self.session.cookies.get('csrftoken'),
         'X-Requested-With':
         'XMLHttpRequest',
         'Referer':
         self.BASE_URL,
         'User-Agent':
         'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
         'Chrome/80.0.3987.163 Safari/537.36',
         'Content-Type':
         'application/x-www-form-urlencoded; charset=UTF-8'
     }
     resp = self.session.post(self.BASE_URL + self.AVAILABILITY_ENDPOINT,
                              data=payload,
                              headers=self.headers)
     if not resp:
         logger.log("error", "Could not check for delivery slot.")
         return False, resp
     data = resp.json()
     if data['status'] == "failure":
         logger.log("info", "No delivery slot is found.")
         return False, resp
     else:
         return True, resp
Ejemplo n.º 11
0
 def load_session(self) -> Session:
     logger.log("info", "Loading previous session...")
     with open(self.session_pickle_filename, 'rb') as session_pickle:
         return pickle.load(session_pickle)
Ejemplo n.º 12
0
 def save_session(self) -> bool:
     logger.log("info", "Saving current session...")
     with open(self.session_pickle_filename, 'wb') as session_pickle:
         pickle.dump(self.session, session_pickle)
     return True
Ejemplo n.º 13
0
def log_error(ws_err: WorkspaceResponseError, level: int = logging.ERROR):
    """Log a workspace response error"""
    err_str = ws_err.resp_data['error']['message']
    logger.log(level, f'Workspace response error: {err_str}')