Exemplo n.º 1
0
def enqueue_webhook(doc, webhook):
    webhook = dataent.get_doc("Webhook", webhook.get("name"))
    headers = {}
    data = {}
    if webhook.webhook_headers:
        for h in webhook.webhook_headers:
            if h.get("key") and h.get("value"):
                headers[h.get("key")] = h.get("value")
    if webhook.webhook_data:
        for w in webhook.webhook_data:
            for k, v in doc.as_dict().items():
                if k == w.fieldname:
                    data[w.key] = v
    for i in range(3):
        try:
            r = requests.post(webhook.request_url,
                              data=json.dumps(data),
                              headers=headers,
                              timeout=5)
            r.raise_for_status()
            dataent.logger().debug({"webhook_success": r.text})
            break
        except Exception as e:
            dataent.logger().debug({"webhook_error": e, "try": i + 1})
            sleep(3 * i + 1)
            if i != 2:
                continue
            else:
                raise e
Exemplo n.º 2
0
def enqueue_events_for_site(site, queued_jobs):
    def log_and_raise():
        dataent.logger(__name__).error(
            'Exception in Enqueue Events for Site {0}'.format(site) + '\n' +
            dataent.get_traceback())
        raise  # pylint: disable=misplaced-bare-raise

    try:
        dataent.init(site=site)
        if dataent.local.conf.maintenance_mode:
            return

        if dataent.local.conf.pause_scheduler:
            return

        dataent.connect()
        if is_scheduler_disabled():
            return

        enqueue_events(site=site, queued_jobs=queued_jobs)

        dataent.logger(__name__).debug(
            'Queued events for site {0}'.format(site))
    except pymysql.OperationalError as e:
        if e.args[0] == ER.ACCESS_DENIED_ERROR:
            dataent.logger(__name__).debug(
                'Access denied for site {0}'.format(site))
        else:
            log_and_raise()
    except:
        log_and_raise()

    finally:
        dataent.destroy()
Exemplo n.º 3
0
def create_mandate(data):
    data = dataent._dict(data)
    dataent.logger().debug(data)

    mandate = data.get('mandate')

    if dataent.db.exists("GoCardless Mandate", mandate):
        return

    else:
        reference_doc = dataent.db.get_value(
            data.get('reference_doctype'),
            data.get('reference_docname'),
            ["reference_doctype", "reference_name"],
            as_dict=1)
        epaas_customer = dataent.db.get_value(reference_doc.reference_doctype,
                                              reference_doc.reference_name,
                                              ["customer_name"],
                                              as_dict=1)

        try:
            dataent.get_doc({
                "doctype": "GoCardless Mandate",
                "mandate": mandate,
                "customer": epaas_customer.customer_name,
                "gocardless_customer": data.get('customer')
            }).insert(ignore_permissions=True)

        except Exception:
            dataent.log_error(dataent.get_traceback())
Exemplo n.º 4
0
def make_error_snapshot(exception):
    if dataent.conf.disable_error_snapshot:
        return

    logger = dataent.logger(__name__, with_more_info=False)

    try:
        error_id = '{timestamp:s}-{ip:s}-{hash:s}'.format(
            timestamp=cstr(datetime.datetime.now()),
            ip=dataent.local.request_ip or '127.0.0.1',
            hash=dataent.generate_hash(length=3))
        snapshot_folder = get_error_snapshot_path()
        dataent.create_folder(snapshot_folder)

        snapshot_file_path = os.path.join(snapshot_folder,
                                          "{0}.json".format(error_id))
        snapshot = get_snapshot(exception)

        with open(encode(snapshot_file_path), 'wb') as error_file:
            error_file.write(encode(dataent.as_json(snapshot)))

        logger.error('New Exception collected with id: {}'.format(error_id))

    except Exception as e:
        logger.error('Could not take error snapshot: {0}'.format(e),
                     exc_info=True)
Exemplo n.º 5
0
def trigger(site, event, last=None, queued_jobs=(), now=False):
    """Trigger method in hooks.scheduler_events."""

    queue = 'long' if event.endswith('_long') else 'short'
    timeout = queue_timeout[queue]
    if not queued_jobs and not now:
        queued_jobs = get_jobs(site=site, queue=queue)

    if dataent.flags.in_test:
        dataent.flags.ran_schedulers.append(event)

    events_from_hooks = get_scheduler_events(event)
    if not events_from_hooks:
        return

    events = events_from_hooks
    if not now:
        events = []
        if event == "cron":
            for e in events_from_hooks:
                e = cron_map.get(e, e)
                if croniter.is_valid(e):
                    if croniter(e, last).get_next(
                            datetime) <= dataent.utils.now_datetime():
                        events.extend(events_from_hooks[e])
                else:
                    dataent.log_error("Cron string " + e + " is not valid",
                                      "Error triggering cron job")
                    dataent.logger(__name__).error(
                        'Exception in Trigger Events for Site {0}, Cron String {1}'
                        .format(site, e))

        else:
            if croniter(
                    cron_map[event],
                    last).get_next(datetime) <= dataent.utils.now_datetime():
                events.extend(events_from_hooks)

    for handler in events:
        if not now:
            if handler not in queued_jobs:
                enqueue(handler, queue, timeout, event)
        else:
            scheduler_task(site=site, event=event, handler=handler, now=True)
Exemplo n.º 6
0
def scheduler_task(site, event, handler, now=False):
    '''This is a wrapper function that runs a hooks.scheduler_events method'''
    dataent.logger(__name__).info(
        'running {handler} for {site} for event: {event}'.format(
            handler=handler, site=site, event=event))
    try:
        if not now:
            dataent.connect(site=site)

        dataent.flags.in_scheduler = True
        dataent.get_attr(handler)()

    except Exception:
        dataent.db.rollback()
        traceback = log(
            handler,
            "Method: {event}, Handler: {handler}".format(event=event,
                                                         handler=handler))
        dataent.logger(__name__).error(traceback)
        raise

    else:
        dataent.db.commit()

    dataent.logger(__name__).info(
        'ran {handler} for {site} for event: {event}'.format(handler=handler,
                                                             site=site,
                                                             event=event))
Exemplo n.º 7
0
def handle_exception(e):
    response = None
    http_status_code = getattr(e, "http_status_code", 500)
    return_as_message = False

    if dataent.get_request_header('Accept') and (
            dataent.local.is_ajax
            or 'application/json' in dataent.get_request_header('Accept')):
        # handle ajax responses first
        # if the request is ajax, send back the trace or error message
        response = dataent.utils.response.report_error(http_status_code)

    elif (http_status_code == 500 and isinstance(e, pymysql.InternalError)
          and e.args[0] in (ER.LOCK_WAIT_TIMEOUT, ER.LOCK_DEADLOCK)):
        http_status_code = 508

    elif http_status_code == 401:
        dataent.respond_as_web_page(
            _("Session Expired"),
            _("Your session has expired, please login again to continue."),
            http_status_code=http_status_code,
            indicator_color='red')
        return_as_message = True

    elif http_status_code == 403:
        dataent.respond_as_web_page(
            _("Not Permitted"),
            _("You do not have enough permissions to complete the action"),
            http_status_code=http_status_code,
            indicator_color='red')
        return_as_message = True

    elif http_status_code == 404:
        dataent.respond_as_web_page(
            _("Not Found"),
            _("The resource you are looking for is not available"),
            http_status_code=http_status_code,
            indicator_color='red')
        return_as_message = True

    else:
        traceback = "<pre>" + dataent.get_traceback() + "</pre>"
        if dataent.local.flags.disable_traceback:
            traceback = ""

        dataent.respond_as_web_page("Server Error",
                                    traceback,
                                    http_status_code=http_status_code,
                                    indicator_color='red',
                                    width=640)
        return_as_message = True

    if e.__class__ == dataent.AuthenticationError:
        if hasattr(dataent.local, "login_manager"):
            dataent.local.login_manager.clear_cookies()

    if http_status_code >= 500:
        dataent.logger().error('Request Error', exc_info=True)
        make_error_snapshot(e)

    if return_as_message:
        response = dataent.website.render.render(
            "message", http_status_code=http_status_code)

    return response
Exemplo n.º 8
0
 def log_and_raise():
     dataent.logger(__name__).error(
         'Exception in Enqueue Events for Site {0}'.format(site) + '\n' +
         dataent.get_traceback())
     raise  # pylint: disable=misplaced-bare-raise
Exemplo n.º 9
0
def log(event, details):
    dataent.logger().info(details)
Exemplo n.º 10
0
def sendmail(communication_name,
             print_html=None,
             print_format=None,
             attachments=None,
             recipients=None,
             cc=None,
             bcc=None,
             lang=None,
             session=None,
             print_letterhead=None):
    try:

        if lang:
            dataent.local.lang = lang

        if session:
            # hack to enable access to private files in PDF
            session['data'] = dataent._dict(session['data'])
            dataent.local.session.update(session)

        if print_letterhead:
            dataent.flags.print_letterhead = print_letterhead

        # upto 3 retries
        for i in range(3):
            try:
                communication = dataent.get_doc("Communication",
                                                communication_name)
                communication._notify(print_html=print_html,
                                      print_format=print_format,
                                      attachments=attachments,
                                      recipients=recipients,
                                      cc=cc,
                                      bcc=bcc)

            except pymysql.InternalError as e:
                # deadlock, try again
                if e.args[0] == ER.LOCK_DEADLOCK:
                    dataent.db.rollback()
                    time.sleep(1)
                    continue
                else:
                    raise
            else:
                break

    except:
        traceback = log(
            "dataent.core.doctype.communication.email.sendmail",
            dataent.as_json({
                "communication_name": communication_name,
                "print_html": print_html,
                "print_format": print_format,
                "attachments": attachments,
                "recipients": recipients,
                "cc": cc,
                "bcc": bcc,
                "lang": lang
            }))
        dataent.logger(__name__).error(traceback)
        raise