예제 #1
0
def run_flow(oo_url, uuid, user, password, inputs, run_name=None):
    post_data = {}
    post_data['uuid'] = uuid
    post_data['runName'] = run_name
    post_data['logLevel'] = 'DEBUG'
    if (inputs is not None):
        post_data['inputs'] = json.loads(inputs)

    json_post = json.dumps(post_data)

    # run the flow
    url = oo_url + '/rest/v1/executions'
    headers = {
        'Content-type': 'application/json',
    }
    r = requests.post(url,
                      data=json_post,
                      verify=False,
                      headers=headers,
                      auth=HTTPBasicAuth(user, password))

    if (r.reason != 'Created'):
        frappe.throw(_("Error Runnning Flow"), r.reason)

    else:
        response = json.loads(r.text)
        frappe.log(response)
        return response['executionId']
예제 #2
0
def ipn_handler():
	try:
		data = frappe.local.form_dict

		validate_ipn_request(data)

		data.update({
			"payment_gateway": "PayPal"
		})

		doc = frappe.get_doc({
			"data": json.dumps(frappe.local.form_dict),
			"doctype": "Integration Request",
			"integration_type": "Subscription Notification",
			"status": "Queued"
		}).insert(ignore_permissions=True)
		frappe.db.commit()

		frappe.enqueue(method='frappe.integrations.doctype.paypal_settings.paypal_settings.handle_subscription_notification',
			queue='long', timeout=600, is_async=True, **{"doctype": "Integration Request", "docname":  doc.name})

	except frappe.InvalidStatusError:
		pass
	except Exception as e:
		frappe.log(frappe.log_error(title=e))
예제 #3
0
    def create_order(self, **kwargs):
        # Creating Orders https://razorpay.com/docs/api/orders/

        # convert rupees to paisa
        kwargs['amount'] *= 100

        # Create integration log
        integration_request = create_request_log(kwargs, "Host", "Razorpay")

        # Setup payment options
        payment_options = {
            "amount": kwargs.get('amount'),
            "currency": kwargs.get('currency', 'INR'),
            "receipt": kwargs.get('receipt'),
            "payment_capture": kwargs.get('payment_capture')
        }
        if self.api_key and self.api_secret:
            try:
                order = make_post_request("https://api.razorpay.com/v1/orders",
                                          auth=(self.api_key,
                                                self.get_password(
                                                    fieldname="api_secret",
                                                    raise_exception=False)),
                                          data=payment_options)
                order['integration_request'] = integration_request.name
                return order  # Order returned to be consumed by razorpay.js
            except Exception:
                frappe.log(frappe.get_traceback())
                frappe.throw(_("Could not create razorpay order"))
예제 #4
0
def ipn_handler():
	try:
		data = frappe.local.form_dict

		validate_ipn_request(data)

		data.update({
			"payment_gateway": "PayPal"
		})

		doc = frappe.get_doc({
			"data": json.dumps(frappe.local.form_dict),
			"doctype": "Integration Request",
			"integration_type": "Subscription Notification",
			"status": "Queued"
		}).insert(ignore_permissions=True)
		frappe.db.commit()

		frappe.enqueue(method='frappe.integrations.doctype.paypal_settings.paypal_settings.handle_subscription_notification',
			queue='long', timeout=600, is_async=True, **{"doctype": "Integration Request", "docname":  doc.name})

	except frappe.InvalidStatusError:
		pass
	except Exception as e:
		frappe.log(frappe.log_error(title=e))
	def create_order(self, **kwargs):
		# Creating Orders https://midtrans.com/docs/api/orders/

		# convert rupees to paisa
		kwargs['amount'] *= 100

		# Create integration log
		integration_request = create_request_log(kwargs, "Host", "midtrans")

		# Setup payment options
		payment_options = {
			"amount": kwargs.get('amount'),
			"currency": kwargs.get('currency', 'INR'),
			"receipt": kwargs.get('receipt'),
			"payment_capture": kwargs.get('payment_capture')
		}
		controller = frappe.get_doc("midtrans Settings")
		for doc in frappe.get_all("Integration Request", filters={"status": "Authorized", "integration_request_service": "midtrans"}, fields=["name", "data"]):
			data = json.loads(doc.data)
			settings = controller.get_settings(data)

			if self.client_key and self.server_key:
				try:
					order = make_post_request(settings.base_url + "/transactions",
						auth=(self.client_key, self.get_password(fieldname="server_key", raise_exception=False)),
						data=payment_options)
					order['integration_request'] = integration_request.name
					return order # Order returned to be consumed by midtrans.js
				except Exception:
					frappe.log(frappe.get_traceback())
					frappe.throw(_("Could not create midtrans order"))
예제 #6
0
def affirm_callback(checkout_token, reference_doctype, reference_docname):

    frappe.log("""[AFFIRM] Affirm callback request: 
		checkout_token: {0}
		reference_doctype: {1}
		reference_docname: {2}
	""".format(checkout_token, reference_doctype, reference_docname))

    affirm_settings = get_api_config()
    redirect_url = "/integrations/payment-failed"

    authorization_response = requests.post(
        "{api_url}/charges".format(**affirm_settings),
        auth=HTTPBasicAuth(affirm_settings.get('public_api_key'),
                           affirm_settings.get('private_api_key')),
        json={"checkout_token": checkout_token})

    affirm_data = authorization_response.json()
    frappe.log("	Response: {}".format(json.dumps(affirm_data)))

    if affirm_data:
        charge_id = affirm_data.get('id')

        # check if callback already happened
        if affirm_data.get("status_code") == 400 and affirm_data.get(
                "code") == "checkout-token-used":
            frappe.log("	SUCCESS via checkout-token-used")
            charge_id = affirm_data.get('charge_id')
            redirect_url = '/integrations/payment-success'
        elif affirm_data.get("status_code") == 400 and affirm_data.get(
                "type") == "invalid_request":
            frappe.log_error("	ERROR: {}".format(affirm_data.get("message")))
            frappe.msgprint(affirm_data.get("message"))
            redirect_url = "/cart"
        else:
            pr = frappe.get_doc(reference_doctype, reference_docname)

            frappe.log("	Updating Sales Order {}".format(
                affirm_data.get('order_id')))
            order_doc = frappe.get_doc(pr.reference_doctype,
                                       affirm_data.get('order_id'))
            order_doc.affirm_id = charge_id
            order_doc.flags.ignore_permissions = 1
            order_doc.save()

            # on awc you can skip creating an actual payment request and just
            # submit the sales order with this flag
            pr.flags.skip_payment_request = True
            pr.on_payment_authorized("Authorized")

            frappe.db.commit()

            redirect_url = '/integrations/payment-success'
    frappe.local.response["type"] = "redirect"
    frappe.local.response["location"] = get_url(redirect_url)

    frappe.log("	Redirect: {}".format(frappe.local.response["location"]))

    return ""
예제 #7
0
def create_test_user(module):
    try:
        test_user = frappe.new_doc('User')
        test_user.first_name = '{module}'.format(module=module)
        test_user.email = 'testuser.{module}@example.com'.format(module=module)
        test_user.save()
    except DuplicateEntryError:
        frappe.log('Test User Chat Profile exists.')
예제 #8
0
파일: util.py 프로젝트: ESS-LLP/frappe
def create_test_user(module):
	try:
		test_user = frappe.new_doc('User')
		test_user.first_name = '{module}'.format(module = module)
		test_user.email      = 'testuser.{module}@example.com'.format(module = module)
		test_user.save()
	except DuplicateEntryError:
		frappe.log('Test User Chat Profile exists.')
예제 #9
0
def get_attr(cmd):
	"""get method object from cmd"""
	if '.' in cmd:
		method = frappe.get_attr(cmd)
	else:
		method = globals()[cmd]
	frappe.log("method:" + cmd)
	return method
예제 #10
0
def get_dashboard_data(dashboard, user=None, **kwargs):
    dashboards = get_permitted_dashboard(user=user)
    if dashboard not in [dash.name for dash in dashboards]:
        raise frappe.PermissionError
    cache_key = dashboard
    cache = frappe.cache().hget("dashboard", cache_key)
    if cache:
        return cache

    frappe.log("Not serving from cache")
    doc = frappe.get_doc("Renovation Dashboard", dashboard)
    data = doc.ready_chart_data(**kwargs)
    if data and not doc.get("custom_caching", 0):
        frappe.cache().hset('dashboard', cache_key, data)
    return data
예제 #11
0
def on_update(doc):
	if is_bio_plant_room(doc) and doc.plant_room_name != doc.bio_name:
		frappe.log(doc.plant_room_name)
		frappe.log(doc.bio_name)
		try:
			res = call("plant_room_modify", {
				"id": doc.bio_id,
				"name": doc.plant_room_name,
				"location": get_location(),
			})
		except BioTrackClientError as e:
			frappe.throw(cstr(e.message), title="BioTrackTHC sync up failed")
		else:
			frappe.db.set_value(doc.doctype, doc.name, {
				"bio_name": doc.plant_room_name,
				"bio_transactionid": res.get("transactionid")
			}, None, update_modified=False)
예제 #12
0
def update_executions():
    frappe.log("Start Updating Executions")
    pending_executions = frappe.get_all(
        "OO Flow Execution",
        fields=["name", "status"],
        filters=[[
            "status", "in",
            [
                "RUNNING", "PAUSED", "PAUSED_USER_PAUSED",
                "PAUSED_INPUT_REQUIRED", "PAUSED_INPUT_REQUIRED_MANUAL_OP",
                "PAUSED_DISPLAY", "PAUSED_GATED_TRANSITION", "PAUSED_HAND_OFF",
                "PAUSED_INTERRUPT", "PAUSED_NO_WORKERS_IN_GROUP",
                "PAUSED_BRANCH_PAUSED"
            ]
        ]])

    if len(pending_executions) == 0:
        return

    executions_dict = {}
    for item in pending_executions:
        name = item['name']
        executions_dict[name] = item["status"]

    executions_id = ",".join(executions_dict.keys())

    results = get_run_summary_list(executions_id)

    for item in results:
        if item["executionId"] in executions_dict and item[
                'status'] != executions_dict[item["executionId"]]:
            execution = frappe.get_doc("OO Flow Execution",
                                       item["executionId"])
            execution.status = item['status']
            if execution.status == "COMPLETED":
                execution.update_outputs()
                execution.save()

    frappe.db.commit()

    frappe.log("Finish Updating Executions")
예제 #13
0
    def log_query(self, query, values, debug, explain):
        # for debugging in tests
        if frappe.conf.get("allow_tests") and frappe.cache().get_value(
                "flag_print_sql"):
            print(self.mogrify(query, values))

        # debug
        if debug:
            if explain and query.strip().lower().startswith("select"):
                self.explain_query(query, values)
            frappe.errprint(self.mogrify(query, values))

        # info
        if (frappe.conf.get("logging") or False) == 2:
            frappe.log("<<<< query")
            frappe.log(self.mogrify(query, values))
            frappe.log(">>>>")
예제 #14
0
def print_log(data, description=None):
    if (frappe.conf.get("logging") or 0) > 0:
        frappe.log(
            "<<<< BioTrackTHC{description}".format(description=description))
        frappe.log(json.dumps(data))
        frappe.log(">>>>")
예제 #15
0
def create_shift_requests():
    connector = frappe.get_doc('Data Migration Connector',
                               'EMPGHR Weekly Roster Connector')
    print(connector.name)
    empShiftCon = EmployeeShiftConnection(connector)

    query = ("""
				select 
				u.id,
				u.employeeId as employee,
				DATE_FORMAT(es.date_of_joining, '%Y-%m-%d') as from_date,
				DATE_FORMAT(IF(es.date_of_leaving IS NULL OR es.date_of_leaving = '00-00-0000' OR es.date_of_leaving = '', DATE_ADD(DATE_FORMAT(NOW(),'%Y-01-31'), INTERVAL 2 MONTH), es.date_of_leaving), '%Y-%m-%d') as to_date,
				time_format(
					IF(erws.id IS NOT NULL, erws.shift_start, erws_d.shift_start), 
					'%H:%i:%s') AS shift_start,
				time_format(
					IF(
						erws.id IS NOT NULL,
						IF( 
							HOUR(ADDTIME(erws.shift_start, SEC_TO_TIME(erws.working_hours*60*60))) > 23,
							SUBTIME(
								ADDTIME(erws.shift_start, SEC_TO_TIME(erws.working_hours*60*60)),
								SEC_TO_TIME(24*60*60)
							),
							ADDTIME(erws.shift_start, SEC_TO_TIME(erws.working_hours*60*60)) 
						),
						ADDTIME(erws_d.shift_start, SEC_TO_TIME(erws_d.working_hours*60*60))
					) 
					,'%H:%i:%s') AS shift_end,
				IF(erws.id IS NOT NULL, erws.working_hours, erws_d.working_hours) as working_hours,
				IF(erws.id IS NOT NULL, erws.wd1, erws_d.wd1) as 'Monday',
				IF(erws.id IS NOT NULL, erws.wd2, erws_d.wd2) as 'Tuesday',
				IF(erws.id IS NOT NULL, erws.wd3, erws_d.wd3) as 'Wednesday',
				IF(erws.id IS NOT NULL, erws.wd4, erws_d.wd4) as 'Thursday',
				IF(erws.id IS NOT NULL, erws.wd5, erws_d.wd5) as 'Friday',
				IF(erws.id IS NOT NULL, erws.wd6, erws_d.wd6) as 'Saturday',
				IF(erws.id IS NOT NULL, erws.wd7, erws_d.wd7) as 'Sunday'
				from main_users u 
				left join main_employees_summary es on u.id = es.user_id 
				left join main_employee_roster_weekly_schedule erws on u.id = erws.user_id 
				left join main_employee_roster_weekly_schedule erws_d on 0 = erws_d.user_id
				where (u.employeeId IS NOT NULL OR u.employeeId != '') 
				""")
    cursor = empShiftCon.connection.cursor(dictionary=True)

    cursor.execute(query)
    records = []
    for data in cursor:
        try:
            data['employee'] = data['employee'].replace('EMPG', '')
            emp = frappe.db.get_value("Employee", data['employee'])
            if emp is None:
                print('Employee with ID ' + str(data['employee']) +
                      ' not found during shift assignment.')
                frappe.log(
                    str(data['employee']) +
                    ' not found during shift assignment.')

            shift_type_name = data['shift_start'] + ' - ' + data['shift_end']
            off_days_string = empShiftCon.get_holiday_list_name(data)
            if off_days_string != '':
                shift_type_name += ' | ' + off_days_string

            shift_assignment_data = {
                "doctype": "Shift Request",
                "shift_type": shift_type_name,
                "employee": data['employee'],
                "from_date": data['from_date'],
                "to_date": data['to_date'],
                "docstatus": 1
            }

            _filters = shift_assignment_data.copy()
            del (_filters["doctype"])
            if frappe.db.get_value("Shift Request", _filters) is None:
                doc = frappe.get_doc(shift_assignment_data)
                doc.save()
        except Exception as err:
            print(str(err))
            frappe.log(str(err))
            pass
    cursor.close()

    return list(records)
예제 #16
0
def app_error_log(title,error):
    frappe.log(traceback.format_exc())
예제 #17
0
    def get(self,
            remote_objectname,
            fields=None,
            filters=None,
            start=0,
            page_length=10):

        query = ("""
			select 
			u.id,
			u.employeeId as employee,
			DATE_FORMAT(es.date_of_joining, '%Y-%m-%d') as from_date,
			DATE_FORMAT(IF(es.date_of_leaving IS NULL OR es.date_of_leaving = '00-00-0000' OR es.date_of_leaving = '', DATE_ADD(DATE_FORMAT(NOW(),'%Y-01-31'), INTERVAL 2 MONTH), es.date_of_leaving), '%Y-%m-%d') as to_date,
			time_format(
				IF(erws.id IS NOT NULL, erws.shift_start, erws_d.shift_start), 
				'%H:%i:%s') AS shift_start,
			time_format(
				IF(
					erws.id IS NOT NULL,
					IF( 
						HOUR(ADDTIME(erws.shift_start, SEC_TO_TIME(erws.working_hours*60*60))) > 23,
						SUBTIME(
							ADDTIME(erws.shift_start, SEC_TO_TIME(erws.working_hours*60*60)),
							SEC_TO_TIME(24*60*60)
						),
						ADDTIME(erws.shift_start, SEC_TO_TIME(erws.working_hours*60*60)) 
					),
					ADDTIME(erws_d.shift_start, SEC_TO_TIME(erws_d.working_hours*60*60))
				) 
				,'%H:%i:%s') AS shift_end,
			IF(erws.id IS NOT NULL, erws.working_hours, erws_d.working_hours) as working_hours,
			IF(erws.id IS NOT NULL, erws.wd1, erws_d.wd1) as 'Monday',
			IF(erws.id IS NOT NULL, erws.wd2, erws_d.wd2) as 'Tuesday',
			IF(erws.id IS NOT NULL, erws.wd3, erws_d.wd3) as 'Wednesday',
			IF(erws.id IS NOT NULL, erws.wd4, erws_d.wd4) as 'Thursday',
			IF(erws.id IS NOT NULL, erws.wd5, erws_d.wd5) as 'Friday',
			IF(erws.id IS NOT NULL, erws.wd6, erws_d.wd6) as 'Saturday',
			IF(erws.id IS NOT NULL, erws.wd7, erws_d.wd7) as 'Sunday'
			from main_users u 
			left join main_employees_summary es on u.id = es.user_id 
			left join main_employee_roster_weekly_schedule erws on u.id = erws.user_id 
			left join main_employee_roster_weekly_schedule erws_d on 0 = erws_d.user_id
			where (u.employeeId IS NOT NULL OR u.employeeId != '' limit 10)
			""")
        cursor = self.connection.cursor(dictionary=True)

        cursor.execute(query)
        records = []
        for data in cursor:
            data['employee'] = data['employee'].replace('EMPG', '')
            emp = frappe.db.get_value("Employee", data['employee'])
            if emp is None:
                frappe.log(str(emp) + ' not found during shift assignment.')

            shift_type_name = data['shift_start'] + ' - ' + data['shift_end']
            off_days_string = self.get_holiday_list_name(data)
            if off_days_string != '':
                shift_type_name += ' | ' + off_days_string

            shift_assignment_data = {
                "id": data['id'],
                "shift_type": shift_type_name,
                "employee": data['employee'],
                "from_date": data['from_date'],
                "to_date": data['to_date'],
                "docstatus": 1
            }
            _filters = shift_assignment_data.copy()
            del (_filters["id"])
            if frappe.db.get_value("Shift Request", _filters) is None:
                records.append(shift_assignment_data)
        cursor.close()

        return list(records)
예제 #18
0
def print_log(data, description=None):
	if (frappe.conf.get("logging") or 0) > 0:
		frappe.log("<<<< BioTrackTHC{description}".format(description=description))
		frappe.log(json.dumps(data))
		frappe.log(">>>>")
예제 #19
0
	def sql(self, query, values=(), as_dict = 0, as_list = 0, formatted = 0,
		debug=0, ignore_ddl=0, as_utf8=0, auto_commit=0, update=None):
		"""Execute a SQL query and fetch all rows.

		:param query: SQL query.
		:param values: List / dict of values to be escaped and substituted in the query.
		:param as_dict: Return as a dictionary.
		:param as_list: Always return as a list.
		:param formatted: Format values like date etc.
		:param debug: Print query and `EXPLAIN` in debug log.
		:param ignore_ddl: Catch exception if table, column missing.
		:param as_utf8: Encode values as UTF 8.
		:param auto_commit: Commit after executing the query.
		:param update: Update this dict to all rows (if returned `as_dict`).

		Examples:

			# return customer names as dicts
			frappe.db.sql("select name from tabCustomer", as_dict=True)

			# return names beginning with a
			frappe.db.sql("select name from tabCustomer where name like %s", "a%")

			# values as dict
			frappe.db.sql("select name from tabCustomer where name like %(name)s and owner=%(owner)s",
				{"name": "a%", "owner":"*****@*****.**"})

		"""
		if not self._conn:
			self.connect()

		# in transaction validations
		self.check_transaction_status(query)

		# autocommit
		if auto_commit: self.commit()

		# execute
		try:
			if values!=():
				if isinstance(values, dict):
					values = dict(values)

				# MySQL-python==1.2.5 hack!
				if not isinstance(values, (dict, tuple, list)):
					values = (values,)

				if debug:
					try:
						self.explain_query(query, values)
						frappe.errprint(query % values)
					except TypeError:
						frappe.errprint([query, values])

				if (frappe.conf.get("logging") or False)==2:
					frappe.log("<<<< query")
					frappe.log(query)
					frappe.log("with values:")
					frappe.log(values)
					frappe.log(">>>>")
				self._cursor.execute(query, values)

			else:
				if debug:
					self.explain_query(query)
					frappe.errprint(query)
				if (frappe.conf.get("logging") or False)==2:
					frappe.log("<<<< query")
					frappe.log(query)
					frappe.log(">>>>")

				self._cursor.execute(query)

		except Exception, e:
			# ignore data definition errors
			if ignore_ddl and e.args[0] in (1146,1054,1091):
				pass

			# NOTE: causes deadlock
			# elif e.args[0]==2006:
			# 	# mysql has gone away
			# 	self.connect()
			# 	return self.sql(query=query, values=values,
			# 		as_dict=as_dict, as_list=as_list, formatted=formatted,
			# 		debug=debug, ignore_ddl=ignore_ddl, as_utf8=as_utf8,
			# 		auto_commit=auto_commit, update=update)

			else:
				raise
예제 #20
0
def create_shifts():
    connector = frappe.get_doc('Data Migration Connector',
                               'EMPGHR Weekly Roster Connector')
    print(connector.name)
    empShiftCon = EmployeeShiftConnection(connector)

    query = ("""
				select 
				u.id,
				u.employeeId as employee,
				DATE_FORMAT(es.date_of_joining, '%Y-%m-%d') as from_date,
				DATE_FORMAT(IF(es.date_of_leaving IS NULL OR es.date_of_leaving = '00-00-0000' OR es.date_of_leaving = '', DATE_ADD(DATE_FORMAT(NOW(),'%Y-01-31'), INTERVAL 2 MONTH), es.date_of_leaving), '%Y-%m-%d') as to_date,
				time_format(
					IF(erws.id IS NOT NULL, erws.shift_start, erws_d.shift_start), 
					'%H:%i:%s') AS shift_start,
				time_format(
					IF(
						erws.id IS NOT NULL,
						IF( 
							HOUR(ADDTIME(erws.shift_start, SEC_TO_TIME(erws.working_hours*60*60))) > 23,
							SUBTIME(
								ADDTIME(erws.shift_start, SEC_TO_TIME(erws.working_hours*60*60)),
								SEC_TO_TIME(24*60*60)
							),
							ADDTIME(erws.shift_start, SEC_TO_TIME(erws.working_hours*60*60)) 
						),
						ADDTIME(erws_d.shift_start, SEC_TO_TIME(erws_d.working_hours*60*60))
					) 
					,'%H:%i:%s') AS shift_end,
				IF(erws.id IS NOT NULL, erws.working_hours, erws_d.working_hours) as working_hours,
				IF(erws.id IS NOT NULL, erws.wd1, erws_d.wd1) as 'Monday',
				IF(erws.id IS NOT NULL, erws.wd2, erws_d.wd2) as 'Tuesday',
				IF(erws.id IS NOT NULL, erws.wd3, erws_d.wd3) as 'Wednesday',
				IF(erws.id IS NOT NULL, erws.wd4, erws_d.wd4) as 'Thursday',
				IF(erws.id IS NOT NULL, erws.wd5, erws_d.wd5) as 'Friday',
				IF(erws.id IS NOT NULL, erws.wd6, erws_d.wd6) as 'Saturday',
				IF(erws.id IS NOT NULL, erws.wd7, erws_d.wd7) as 'Sunday'
				from main_users u 
				left join main_employees_summary es on u.id = es.user_id 
				left join main_employee_roster_weekly_schedule erws on u.id = erws.user_id 
				left join main_employee_roster_weekly_schedule erws_d on 0 = erws_d.user_id
				where (u.employeeId IS NOT NULL OR u.employeeId != '')
				""")
    cursor = empShiftCon.connection.cursor(dictionary=True)

    cursor.execute(query)
    records = []
    for data in cursor:
        try:
            data['employee'] = data['employee'].replace('EMPG', '')
            shift_type_name = empShiftCon.get_shift_type_name(data)
            print(shift_type_name)
            if not frappe.db.exists("Shift Type", shift_type_name):
                empShiftCon.create_shift_type(data)
            emp = frappe.db.get_value("Employee", data['employee'])
            if emp is not None:
                emp_doc = frappe.get_doc("Employee", data['employee'])
                emp_doc.shift_type = shift_type_name
                emp_doc.save()
        except Exception as err:
            print(str(err))
            frappe.log(str(err))
            pass
    cursor.close()

    return list(records)
예제 #21
0
def create_ebay_features_cache(features_data):
    """Create SQL caches for the features dictionaries"""

    tables_list = frappe.db.get_tables()  # Note that db.table_exists is broken

    # Check the categories tables exist
    if not ('eBay_categories_info' in tables_list
            or 'eBay_categories_hierarchy' in tables_list):
        raise ValueError('Categories cache does not exist!')

    # Drop the tables if they exist
    if 'eBay_features_info' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features_info""")
    if 'eBay_features_PaymentMethodConnections' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features_PaymentMethodConnections""")
    if 'eBay_features_extra' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features_extra""")
    if 'eBay_features' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features""")
    if 'eBay_features_ListingDurations' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features_ListingDurations""")
    if 'eBay_features_FeatureDefinitions' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features_FeatureDefinitions""")
    if 'eBay_features_ConditionValues' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features_ConditionValues""")
    if 'eBay_features_PaymentMethods' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features_PaymentMethods""")
    if 'eBay_features_ListingDurationTokens' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features_ListingDurationTokens""")


# Create the tables

# Lookup tables for hard-coded eBay tokens
    frappe.db.sql("""
        CREATE TABLE eBay_features_ListingDurationTokens (
            ListingDurationToken NVARCHAR(20),
            Days INT,
            Description NVARCHAR(1000),
            PRIMARY KEY (ListingDurationToken)
        )""")

    frappe.db.sql("""
        CREATE TABLE eBay_features_PaymentMethods (
            PaymentMethod NVARCHAR(100),
            Description NVARCHAR(1000),
            PRIMARY KEY (PaymentMethod)
        )""")

    # Tables for the features data
    frappe.db.sql("""
        CREATE TABLE eBay_features_info (
            Build NVARCHAR(1000),
            CategoryVersion NVARCHAR(1000),
            ListingDurationVersion INT,
            Timestamp NVARCHAR(100),
            UpdateTime NVARCHAR(100),
            Version NVARCHAR(100)
        )""")

    frappe.db.sql("""
        CREATE TABLE eBay_features_ConditionValues (
            CategoryID NVARCHAR(10) NOT NULL,
            ConditionID INT NOT NULL,
            DisplayName NVARCHAR(1000),
            FOREIGN KEY (CategoryID)
                REFERENCES eBay_categories_hierarchy (CategoryID)
        )""")

    frappe.db.sql("""
        CREATE TABLE eBay_features_FeatureDefinitions (
            FeatureDefinition NVARCHAR(""" + EBAY_ATTR_LEN_STR + """),
            Extra BOOLEAN NOT NULL,
            PRIMARY KEY (FeatureDefinition)
        )""")

    frappe.db.sql("""
        CREATE TABLE eBay_features_ListingDurations (
            durationSetID INT NOT NULL,
            ListingDurationToken NVARCHAR(20),
            FOREIGN KEY (ListingDurationToken)
                REFERENCES eBay_features_ListingDurationTokens (
                    ListingDurationToken)
        )""")

    frappe.db.sql("""
        CREATE TABLE eBay_features_PaymentMethodConnections (
            CategoryID NVARCHAR(10) NOT NULL,
            PaymentMethod NVARCHAR(100) NOT NULL,
            FOREIGN KEY (CategoryID)
                REFERENCES eBay_categories_hierarchy (CategoryID),
            FOREIGN KEY (PaymentMethod)
                REFERENCES eBay_features_PaymentMethods (PaymentMethod)
        )""")

    # NOTE - changes here should be matched by changes to the
    # FEATURES_BASE_COLUMNS constant
    frappe.db.sql("""
        CREATE TABLE eBay_features (
            CategoryID NVARCHAR(10) NOT NULL,
            ListingDurationAdType INT,
            ListingDurationAuction INT,
            ListingDurationChinese INT,
            ListingDurationDutch INT,
            ListingDurationLive INT,
            ListingDurationFixedPriceItem INT,
            ListingDurationLeadGeneration INT,
            ListingDurationPersonalOffer INT,
            ListingDurationStoresFixedPrice INT,
            CompatibleVehicleType NVARCHAR(100),
            ExpressEnabled BOOLEAN,
            GlobalShippingEnabled BOOLEAN,
            MaxFlatShippingCost DOUBLE PRECISION,
            MaxFlatShippingCostCurrency NVARCHAR(10),
            ConditionEnabled NVARCHAR(100),
            ConditionHelpURL NVARCHAR(1000),
            FOREIGN KEY (CategoryID)
                REFERENCES eBay_categories_hierarchy (CategoryID)
        )""")

    frappe.db.sql("""
        CREATE TABLE eBay_features_extra (
            CategoryID NVARCHAR(10) NOT NULL,
            Attribute NVARCHAR(""" + EBAY_ATTR_LEN_STR + """) NOT NULL,
            Value NVARCHAR(""" + EBAY_VALUE_LEN_STR + """),
            FOREIGN KEY (CategoryID)
                REFERENCES eBay_categories_hierarchy (CategoryID),
            UNIQUE cat_attr (CategoryID, Attribute)
        )""")

    # Set up the tables with hard-coded eBay constants

    # Set up the eBay_features_ListingDurationTokens table
    for values in LISTING_DURATION_TOKENS:
        frappe.db.sql(
            """
            INSERT INTO eBay_features_ListingDurationTokens
                (ListingDurationToken, Days, Description)
                VALUES (%s, %s, %s)
            """, values)

    for key, value in PAYMENT_METHODS.items():
        frappe.db.sql(
            """
            INSERT INTO eBay_features_PaymentMethods
                (PaymentMethod, Description)
                VALUES (%s, %s)
            """, (key, value))

    frappe.db.commit()

    # Set up the tables for the features data

    # Load the basic info into the info table
    info_od = collections.OrderedDict()
    keys = ('Build', 'CategoryVersion', 'ListingDurationVersion', 'Timestamp',
            'UpdateTime', 'Version')
    for key in keys:
        if key in features_data:
            info_od[key] = features_data[key]
        else:
            info_od[key] = False
    frappe.db.sql(
        """
        INSERT INTO eBay_features_info (""" + ", ".join(info_od.keys()) + """)
            VALUES (""" + _s_for(info_od.values()) + """)
        """, info_od.values())

    # Set up the eBay_features_FeatureDefinitions table
    for fd in features_data['FeatureDefinitions']:
        if fd in FEATURES_NOT_SUPPORTED:
            continue
        extra = fd not in FEATURES_NOT_EXTRA
        frappe.db.sql(
            """
            INSERT INTO eBay_features_FeatureDefinitions
                (FeatureDefinition, Extra)
                VALUES (%s, %s)
            """, (fd, extra))

    # Set up the eBay_features_ListingDurations table
    for ld_key, tokens in features_data['ListingDurations'].items():
        if isinstance(tokens, six.string_types):
            tokens = (tokens, )
        for token in tokens:
            frappe.db.sql(
                """
                INSERT INTO eBay_features_ListingDurations
                    (durationSetID, ListingDurationToken)
                    VALUES (%s, %s)
                """, (ld_key, token))

    # Loop over categories, setting up the remaining tables
    cat_keys = FEATURES_BASE_COLUMNS

    # First set up the ROOT (CategoryID = 0) element with the SiteDefaults
    root_cat = features_data['SiteDefaults'].copy()
    root_cat['CategoryID'] = 0
    features_data['Category'].insert(0, root_cat)

    local_unsupported = []
    for cat in features_data['Category']:
        # OrderedDict to store values for main table
        cat_od = collections.OrderedDict()
        for key in cat_keys:
            cat_od[key] = None
        cat_id = cat['CategoryID']
        # Loop over attributes and values
        for key, value in cat.items():
            if key == 'ListingDuration':
                if not isinstance(value, collections.Sequence):
                    value = (value, )
                for ld_dict in value:
                    ld_key_str = 'ListingDuration' + ld_dict['_type']
                    cat_od[ld_key_str] = ld_dict['value']
            elif key == 'PaymentMethod':
                if isinstance(value, six.string_types):
                    value = (value, )
                for payment_method in value:
                    frappe.db.sql(
                        """
                        INSERT INTO eBay_features_PaymentMethodConnections (
                            CategoryID, PaymentMethod )
                            VALUES (%s, %s)
                        """, (cat_id, payment_method))
            elif key == 'ConditionValues':
                if not isinstance(value, collections.Sequence):
                    value = (value, )
                for cv_dict in value:
                    frappe.db.sql(
                        """
                        INSERT INTO eBay_features_ConditionValues (
                            CategoryID, ConditionID, DisplayName )
                            VALUES (%s, %s, %s)
                        """, (cat_id, cv_dict['ID'], cv_dict['DisplayName']))
            elif key == 'MaxFlatShippingCost':
                cat_od['MaxFlatShippingCostCurrency'] = value['_currencyID']
                cat_od['MaxFlatShippingCost'] = value['value']
            elif key in cat_keys:
                # This is one of the expected keys
                cat_od[key] = value
            else:
                # This is an 'extra' key
                if key in FEATURES_NOT_SUPPORTED:
                    continue
                if key in local_unsupported:
                    continue
                if (not isinstance(value, six.string_types)
                        or len(key) > EBAY_ATTR_LEN
                        or len(value) > EBAY_VALUE_LEN):
                    print('Unsupported eBay attribute/value: {} : {}'.format(
                        key, value))
                    frappe.log(
                        'Unsupported eBay attribute/value: {} : {}'.format(
                            key, value))
                    local_unsupported.append(key)
                    raise ValueError('Fancy unsupported data type!')
                frappe.db.sql(
                    """
                    INSERT INTO eBay_features_extra (
                        CategoryID, Attribute, Value )
                        VALUES (%s, %s, %s)
                """, (cat_id, key, value))

        # Insert the completed row for this category
        frappe.db.sql(
            """
            INSERT INTO eBay_features (""" + ", ".join(cat_od.keys()) + """)
                VALUES (""" + _s_for(cat_od.values()) + """)
            """, cat_od.values())

    frappe.db.commit()
예제 #22
0
    def sql(self,
            query,
            values=(),
            as_dict=0,
            as_list=0,
            formatted=0,
            debug=0,
            ignore_ddl=0,
            as_utf8=0,
            auto_commit=0,
            update=None):
        """
		      * Execute a `query`, with given `values`
		      * returns as a dictionary if as_dict = 1
		      * returns as a list of lists (with cleaned up dates) if as_list = 1
		"""
        if not self._conn:
            self.connect()

        # in transaction validations
        self.check_transaction_status(query)

        # autocommit
        if auto_commit: self.commit()

        # execute
        try:
            if values != ():
                if isinstance(values, dict):
                    values = dict(values)

                # MySQL-python==1.2.5 hack!
                if not isinstance(values, (dict, tuple, list)):
                    values = (values, )

                if debug:
                    try:
                        self.explain_query(query, values)
                        frappe.errprint(query % values)
                    except TypeError:
                        frappe.errprint([query, values])
                if (frappe.conf.get("logging") or False) == 2:
                    frappe.log("<<<< query")
                    frappe.log(query)
                    frappe.log("with values:")
                    frappe.log(values)
                    frappe.log(">>>>")

                self._cursor.execute(query, values)

            else:
                if debug:
                    self.explain_query(query)
                    frappe.errprint(query)
                if (frappe.conf.get("logging") or False) == 2:
                    frappe.log("<<<< query")
                    frappe.log(query)
                    frappe.log(">>>>")

                self._cursor.execute(query)
        except Exception, e:
            # ignore data definition errors
            if ignore_ddl and e.args[0] in (1146, 1054, 1091):
                pass
            else:
                raise
예제 #23
0
    def sql(self,
            query,
            values=(),
            as_dict=0,
            as_list=0,
            formatted=0,
            debug=0,
            ignore_ddl=0,
            as_utf8=0,
            auto_commit=0,
            update=None,
            explain=False):
        """Execute a SQL query and fetch all rows.

		:param query: SQL query.
		:param values: List / dict of values to be escaped and substituted in the query.
		:param as_dict: Return as a dictionary.
		:param as_list: Always return as a list.
		:param formatted: Format values like date etc.
		:param debug: Print query and `EXPLAIN` in debug log.
		:param ignore_ddl: Catch exception if table, column missing.
		:param as_utf8: Encode values as UTF 8.
		:param auto_commit: Commit after executing the query.
		:param update: Update this dict to all rows (if returned `as_dict`).

		Examples:

			# return customer names as dicts
			frappe.db.sql("select name from tabCustomer", as_dict=True)

			# return names beginning with a
			frappe.db.sql("select name from tabCustomer where name like %s", "a%")

			# values as dict
			frappe.db.sql("select name from tabCustomer where name like %(name)s and owner=%(owner)s",
				{"name": "a%", "owner":"*****@*****.**"})

		"""
        if re.search(r'ifnull\(', query, flags=re.IGNORECASE):
            # replaces ifnull in query with coalesce
            query = re.sub(r'ifnull\(',
                           'coalesce(',
                           query,
                           flags=re.IGNORECASE)

        if not self._conn:
            self.connect()

        # in transaction validations
        self.check_transaction_status(query)

        # autocommit
        if auto_commit: self.commit()

        # execute
        try:
            if debug:
                time_start = time()

            if values != ():
                if isinstance(values, dict):
                    values = dict(values)

                # MySQL-python==1.2.5 hack!
                if not isinstance(values, (dict, tuple, list)):
                    values = (values, )

                if debug and query.strip().lower().startswith('select'):
                    try:
                        if explain:
                            self.explain_query(query, values)
                        frappe.errprint(query % values)
                    except TypeError:
                        frappe.errprint([query, values])
                if (frappe.conf.get("logging") or False) == 2:
                    frappe.log("<<<< query")
                    frappe.log(query)
                    frappe.log("with values:")
                    frappe.log(values)
                    frappe.log(">>>>")
                self._cursor.execute(query, values)

                if frappe.flags.in_migrate:
                    self.log_touched_tables(query, values)

            else:
                if debug:
                    if explain:
                        self.explain_query(query)
                    frappe.errprint(query)
                if (frappe.conf.get("logging") or False) == 2:
                    frappe.log("<<<< query")
                    frappe.log(query)
                    frappe.log(">>>>")

                self._cursor.execute(query)

                if frappe.flags.in_migrate:
                    self.log_touched_tables(query)

            if debug:
                time_end = time()
                frappe.errprint(("Execution time: {0} sec").format(
                    round(time_end - time_start, 2)))

        except Exception as e:
            if frappe.conf.db_type == 'postgres':
                self.rollback()

            elif self.is_syntax_error(e):
                # only for mariadb
                frappe.errprint('Syntax error in query:')
                frappe.errprint(query)

            if ignore_ddl and (self.is_missing_column(e)
                               or self.is_missing_table(e)
                               or self.cant_drop_field_or_key(e)):
                pass
            else:
                raise

        if auto_commit: self.commit()

        if not self._cursor.description:
            return ()

        # scrub output if required
        if as_dict:
            ret = self.fetch_as_dict(formatted, as_utf8)
            if update:
                for r in ret:
                    r.update(update)
            return ret
        elif as_list:
            return self.convert_to_lists(self._cursor.fetchall(), formatted,
                                         as_utf8)
        elif as_utf8:
            return self.convert_to_lists(self._cursor.fetchall(), formatted,
                                         as_utf8)
        else:
            return self._cursor.fetchall()
예제 #24
0
	def sql(self, query, values=(), as_dict = 0, as_list = 0, formatted = 0,
		debug=0, ignore_ddl=0, as_utf8=0, auto_commit=0, update=None):
		"""Execute a SQL query and fetch all rows.

		:param query: SQL query.
		:param values: List / dict of values to be escaped and substituted in the query.
		:param as_dict: Return as a dictionary.
		:param as_list: Always return as a list.
		:param formatted: Format values like date etc.
		:param debug: Print query and `EXPLAIN` in debug log.
		:param ignore_ddl: Catch exception if table, column missing.
		:param as_utf8: Encode values as UTF 8.
		:param auto_commit: Commit after executing the query.
		:param update: Update this dict to all rows (if returned `as_dict`).

		Examples:

			# return customer names as dicts
			frappe.db.sql("select name from tabCustomer", as_dict=True)

			# return names beginning with a
			frappe.db.sql("select name from tabCustomer where name like %s", "a%")

			# values as dict
			frappe.db.sql("select name from tabCustomer where name like %(name)s and owner=%(owner)s",
				{"name": "a%", "owner":"*****@*****.**"})

		"""
		if not self._conn:
			self.connect()

		# in transaction validations
		self.check_transaction_status(query)

		# autocommit
		if auto_commit: self.commit()

		# execute
		try:
			if values!=():
				if isinstance(values, dict):
					values = dict(values)

				# MySQL-python==1.2.5 hack!
				if not isinstance(values, (dict, tuple, list)):
					values = (values,)

				if debug:
					try:
						self.explain_query(query, values)
						frappe.errprint(query % values)
					except TypeError:
						frappe.errprint([query, values])
				if (frappe.conf.get("logging") or False)==2:
					frappe.log("<<<< query")
					frappe.log(query)
					frappe.log("with values:")
					frappe.log(values)
					frappe.log(">>>>")
				self._cursor.execute(query, values)

			else:
				if debug:
					self.explain_query(query)
					frappe.errprint(query)
				if (frappe.conf.get("logging") or False)==2:
					frappe.log("<<<< query")
					frappe.log(query)
					frappe.log(">>>>")

				self._cursor.execute(query)
		except Exception, e:
			# ignore data definition errors
			if ignore_ddl and e.args[0] in (1146,1054,1091):
				pass
			else:
				raise
예제 #25
0
파일: database.py 프로젝트: frappe/frappe
	def sql(self, query, values=(), as_dict = 0, as_list = 0, formatted = 0,
		debug=0, ignore_ddl=0, as_utf8=0, auto_commit=0, update=None, explain=False):
		"""Execute a SQL query and fetch all rows.

		:param query: SQL query.
		:param values: List / dict of values to be escaped and substituted in the query.
		:param as_dict: Return as a dictionary.
		:param as_list: Always return as a list.
		:param formatted: Format values like date etc.
		:param debug: Print query and `EXPLAIN` in debug log.
		:param ignore_ddl: Catch exception if table, column missing.
		:param as_utf8: Encode values as UTF 8.
		:param auto_commit: Commit after executing the query.
		:param update: Update this dict to all rows (if returned `as_dict`).

		Examples:

			# return customer names as dicts
			frappe.db.sql("select name from tabCustomer", as_dict=True)

			# return names beginning with a
			frappe.db.sql("select name from tabCustomer where name like %s", "a%")

			# values as dict
			frappe.db.sql("select name from tabCustomer where name like %(name)s and owner=%(owner)s",
				{"name": "a%", "owner":"*****@*****.**"})

		"""
		if not self._conn:
			self.connect()

		# in transaction validations
		self.check_transaction_status(query)

		# autocommit
		if auto_commit: self.commit()

		# execute
		try:
			if debug:
				time_start = time()

			if values!=():
				if isinstance(values, dict):
					values = dict(values)

				# MySQL-python==1.2.5 hack!
				if not isinstance(values, (dict, tuple, list)):
					values = (values,)

				if debug and query.strip().lower().startswith('select'):
					try:
						if explain:
							self.explain_query(query, values)
						frappe.errprint(query % values)
					except TypeError:
						frappe.errprint([query, values])
				if (frappe.conf.get("logging") or False)==2:
					frappe.log("<<<< query")
					frappe.log(query)
					frappe.log("with values:")
					frappe.log(values)
					frappe.log(">>>>")
				self._cursor.execute(query, values)

				if frappe.flags.in_migrate:
					self.log_touched_tables(query, values)

			else:
				if debug:
					if explain:
						self.explain_query(query)
					frappe.errprint(query)
				if (frappe.conf.get("logging") or False)==2:
					frappe.log("<<<< query")
					frappe.log(query)
					frappe.log(">>>>")

				self._cursor.execute(query)

				if frappe.flags.in_migrate:
					self.log_touched_tables(query)

			if debug:
				time_end = time()
				frappe.errprint(("Execution time: {0} sec").format(round(time_end - time_start, 2)))

		except Exception as e:
			if ignore_ddl and e.args[0] in (ER.BAD_FIELD_ERROR, ER.NO_SUCH_TABLE,
				ER.CANT_DROP_FIELD_OR_KEY):
				pass

			# NOTE: causes deadlock
			# elif e.args[0]==2006:
			# 	# mysql has gone away
			# 	self.connect()
			# 	return self.sql(query=query, values=values,
			# 		as_dict=as_dict, as_list=as_list, formatted=formatted,
			# 		debug=debug, ignore_ddl=ignore_ddl, as_utf8=as_utf8,
			# 		auto_commit=auto_commit, update=update)
			else:
				raise

		if auto_commit: self.commit()

		# scrub output if required
		if as_dict:
			ret = self.fetch_as_dict(formatted, as_utf8)
			if update:
				for r in ret:
					r.update(update)
			return ret
		elif as_list:
			return self.convert_to_lists(self._cursor.fetchall(), formatted, as_utf8)
		elif as_utf8:
			return self.convert_to_lists(self._cursor.fetchall(), formatted, as_utf8)
		else:
			return self._cursor.fetchall()
예제 #26
0
파일: database.py 프로젝트: vrms/frappe
    def sql(self,
            query,
            values=(),
            as_dict=0,
            as_list=0,
            formatted=0,
            debug=0,
            ignore_ddl=0,
            as_utf8=0,
            auto_commit=0,
            update=None,
            explain=False):
        """Execute a SQL query and fetch all rows.

		:param query: SQL query.
		:param values: List / dict of values to be escaped and substituted in the query.
		:param as_dict: Return as a dictionary.
		:param as_list: Always return as a list.
		:param formatted: Format values like date etc.
		:param debug: Print query and `EXPLAIN` in debug log.
		:param ignore_ddl: Catch exception if table, column missing.
		:param as_utf8: Encode values as UTF 8.
		:param auto_commit: Commit after executing the query.
		:param update: Update this dict to all rows (if returned `as_dict`).

		Examples:

			# return customer names as dicts
			frappe.db.sql("select name from tabCustomer", as_dict=True)

			# return names beginning with a
			frappe.db.sql("select name from tabCustomer where name like %s", "a%")

			# values as dict
			frappe.db.sql("select name from tabCustomer where name like %(name)s and owner=%(owner)s",
				{"name": "a%", "owner":"*****@*****.**"})

		"""
        if not self._conn:
            self.connect()

        # in transaction validations
        self.check_transaction_status(query)

        # autocommit
        if auto_commit: self.commit()

        # execute
        try:
            if debug:
                time_start = time()

            if values != ():
                if isinstance(values, dict):
                    values = dict(values)

                # MySQL-python==1.2.5 hack!
                if not isinstance(values, (dict, tuple, list)):
                    values = (values, )

                if debug and query.strip().lower().startswith('select'):
                    try:
                        if explain:
                            self.explain_query(query, values)
                        frappe.errprint(query % values)
                    except TypeError:
                        frappe.errprint([query, values])
                if (frappe.conf.get("logging") or False) == 2:
                    frappe.log("<<<< query")
                    frappe.log(query)
                    frappe.log("with values:")
                    frappe.log(values)
                    frappe.log(">>>>")
                self._cursor.execute(query, values)
            else:
                if debug:
                    if explain:
                        self.explain_query(query)
                    frappe.errprint(query)
                if (frappe.conf.get("logging") or False) == 2:
                    frappe.log("<<<< query")
                    frappe.log(query)
                    frappe.log(">>>>")

                self._cursor.execute(query)

            if debug:
                time_end = time()
                frappe.errprint(("Execution time: {0} sec").format(
                    round(time_end - time_start, 2)))

        except Exception as e:
            if ignore_ddl and e.args[0] in (ER.BAD_FIELD_ERROR,
                                            ER.NO_SUCH_TABLE,
                                            ER.CANT_DROP_FIELD_OR_KEY):
                pass

            # NOTE: causes deadlock
            # elif e.args[0]==2006:
            # 	# mysql has gone away
            # 	self.connect()
            # 	return self.sql(query=query, values=values,
            # 		as_dict=as_dict, as_list=as_list, formatted=formatted,
            # 		debug=debug, ignore_ddl=ignore_ddl, as_utf8=as_utf8,
            # 		auto_commit=auto_commit, update=update)
            else:
                raise

        if auto_commit: self.commit()

        # scrub output if required
        if as_dict:
            ret = self.fetch_as_dict(formatted, as_utf8)
            if update:
                for r in ret:
                    r.update(update)
            return ret
        elif as_list:
            return self.convert_to_lists(self._cursor.fetchall(), formatted,
                                         as_utf8)
        elif as_utf8:
            return self.convert_to_lists(self._cursor.fetchall(), formatted,
                                         as_utf8)
        else:
            return self._cursor.fetchall()
예제 #27
0
	def sql(self, query, values=(), as_dict = 0, as_list = 0, formatted = 0,
		debug=0, ignore_ddl=0, as_utf8=0, auto_commit=0, update=None):
		"""
		      * Execute a `query`, with given `values`
		      * returns as a dictionary if as_dict = 1
		      * returns as a list of lists (with cleaned up dates) if as_list = 1
		"""
		if not self._conn:
			self.connect()

		# in transaction validations
		self.check_transaction_status(query)

		# autocommit
		if auto_commit: self.commit()

		# execute
		try:
			if values!=():
				if isinstance(values, dict):
					values = dict(values)

				# MySQL-python==1.2.5 hack!
				if not isinstance(values, (dict, tuple, list)):
					values = (values,)

				if debug:
					try:
						self.explain_query(query, values)
						frappe.errprint(query % values)
					except TypeError:
						frappe.errprint([query, values])
				if (frappe.conf.get("logging") or False)==2:
					frappe.log("<<<< query")
					frappe.log(query)
					frappe.log("with values:")
					frappe.log(values)
					frappe.log(">>>>")
				#print query
				#print values
				self._cursor.execute(query, values)

			else:
				if debug:
					self.explain_query(query)
					frappe.errprint(query)
				if (frappe.conf.get("logging") or False)==2:
					frappe.log("<<<< query")
					frappe.log(query)
					frappe.log(">>>>")
				#frappe.errprint(query)
				self._cursor.execute(query)
		except Exception, e:
			# ignore data definition errors
			if ignore_ddl and e.args[0] in (1146,1054,1091):
				pass
			else:
				raise
				if isinstance(values, dict):
					values = dict(values)

				# MySQL-python==1.2.5 hack!
				if not isinstance(values, (dict, tuple, list)):
					values = (values,)

				if debug:
					try:
						self.explain_query(query, values)
						frappe.errprint(query % values)
					except TypeError:
						frappe.errprint([query, values])

				if (frappe.conf.get("logging") or False)==2:
					frappe.log("<<<< query")
					frappe.log(query)
					frappe.log("with values:")
					frappe.log(values)
					frappe.log(">>>>")
				self._cursor.execute(query, values)

			else:
				if debug:
					self.explain_query(query)
					frappe.errprint(query)
				if (frappe.conf.get("logging") or False)==2:
					frappe.log("<<<< query")
					frappe.log(query)
					frappe.log(">>>>")
예제 #29
0
def create_ebay_features_cache(features_data):
    """Create SQL caches for the features dictionaries"""

    tables_list = frappe.db.get_tables()  # Note that db.table_exists is broken

    # Check the categories tables exist
    if not ('eBay_categories_info' in tables_list
            or 'eBay_categories_hierarchy' in tables_list):
        raise ValueError('Categories cache does not exist!')

    # Drop the tables if they exist
    if 'eBay_features_info' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features_info""")
    if 'eBay_features_PaymentMethodConnections' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features_PaymentMethodConnections""")
    if 'eBay_features_extra' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features_extra""")
    if 'eBay_features' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features""")
    if 'eBay_features_ListingDurations' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features_ListingDurations""")
    if 'eBay_features_FeatureDefinitions' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features_FeatureDefinitions""")
    if 'eBay_features_ConditionValues' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features_ConditionValues""")
    if 'eBay_features_PaymentMethods' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features_PaymentMethods""")
    if 'eBay_features_ListingDurationTokens' in tables_list:
        frappe.db.sql("""DROP TABLE eBay_features_ListingDurationTokens""")

# Create the tables

    # Lookup tables for hard-coded eBay tokens
    frappe.db.sql("""
        CREATE TABLE eBay_features_ListingDurationTokens (
            ListingDurationToken NVARCHAR(20),
            Days INT,
            Description NVARCHAR(1000),
            PRIMARY KEY (ListingDurationToken)
        )""")

    frappe.db.sql("""
        CREATE TABLE eBay_features_PaymentMethods (
            PaymentMethod NVARCHAR(100),
            Description NVARCHAR(1000),
            PRIMARY KEY (PaymentMethod)
        )""")

    # Tables for the features data
    frappe.db.sql("""
        CREATE TABLE eBay_features_info (
            Build NVARCHAR(1000),
            CategoryVersion NVARCHAR(1000),
            ListingDurationVersion INT,
            Timestamp NVARCHAR(100),
            UpdateTime NVARCHAR(100),
            Version NVARCHAR(100)
        )""")

    frappe.db.sql("""
        CREATE TABLE eBay_features_ConditionValues (
            CategoryID NVARCHAR(10) NOT NULL,
            ConditionID INT NOT NULL,
            DisplayName NVARCHAR(1000),
            FOREIGN KEY (CategoryID)
                REFERENCES eBay_categories_hierarchy (CategoryID)
        )""")

    frappe.db.sql("""
        CREATE TABLE eBay_features_FeatureDefinitions (
            FeatureDefinition NVARCHAR(""" + EBAY_ATTR_LEN_STR + """),
            Extra BOOLEAN NOT NULL,
            PRIMARY KEY (FeatureDefinition)
        )""")

    frappe.db.sql("""
        CREATE TABLE eBay_features_ListingDurations (
            durationSetID INT NOT NULL,
            ListingDurationToken NVARCHAR(20),
            FOREIGN KEY (ListingDurationToken)
                REFERENCES eBay_features_ListingDurationTokens (
                    ListingDurationToken)
        )""")

    frappe.db.sql("""
        CREATE TABLE eBay_features_PaymentMethodConnections (
            CategoryID NVARCHAR(10) NOT NULL,
            PaymentMethod NVARCHAR(100) NOT NULL,
            FOREIGN KEY (CategoryID)
                REFERENCES eBay_categories_hierarchy (CategoryID),
            FOREIGN KEY (PaymentMethod)
                REFERENCES eBay_features_PaymentMethods (PaymentMethod)
        )""")

    # NOTE - changes here should be matched by changes to the
    # FEATURES_BASE_COLUMNS constant
    frappe.db.sql("""
        CREATE TABLE eBay_features (
            CategoryID NVARCHAR(10) NOT NULL,
            ListingDurationAdType INT,
            ListingDurationAuction INT,
            ListingDurationChinese INT,
            ListingDurationDutch INT,
            ListingDurationLive INT,
            ListingDurationFixedPriceItem INT,
            ListingDurationLeadGeneration INT,
            ListingDurationPersonalOffer INT,
            ListingDurationStoresFixedPrice INT,
            CompatibleVehicleType NVARCHAR(100),
            ExpressEnabled BOOLEAN,
            GlobalShippingEnabled BOOLEAN,
            MaxFlatShippingCost DOUBLE PRECISION,
            MaxFlatShippingCostCurrency NVARCHAR(10),
            ConditionEnabled NVARCHAR(100),
            ConditionHelpURL NVARCHAR(1000),
            FOREIGN KEY (CategoryID)
                REFERENCES eBay_categories_hierarchy (CategoryID)
        )""")

    frappe.db.sql("""
        CREATE TABLE eBay_features_extra (
            CategoryID NVARCHAR(10) NOT NULL,
            Attribute NVARCHAR(""" + EBAY_ATTR_LEN_STR + """) NOT NULL,
            Value NVARCHAR(""" + EBAY_VALUE_LEN_STR + """),
            FOREIGN KEY (CategoryID)
                REFERENCES eBay_categories_hierarchy (CategoryID),
            UNIQUE cat_attr (CategoryID, Attribute)
        )""")

    # Set up the tables with hard-coded eBay constants

    # Set up the eBay_features_ListingDurationTokens table
    for values in LISTING_DURATION_TOKENS:
        frappe.db.sql("""
            INSERT INTO eBay_features_ListingDurationTokens
                (ListingDurationToken, Days, Description)
                VALUES (%s, %s, %s)
            """, values)

    for key, value in PAYMENT_METHODS.items():
        frappe.db.sql("""
            INSERT INTO eBay_features_PaymentMethods
                (PaymentMethod, Description)
                VALUES (%s, %s)
            """, (key, value))

    frappe.db.commit()

    # Set up the tables for the features data

    # Load the basic info into the info table
    info_od = collections.OrderedDict()
    keys = ('Build', 'CategoryVersion', 'ListingDurationVersion',
            'Timestamp', 'UpdateTime', 'Version')
    for key in keys:
        if key in features_data:
            info_od[key] = features_data[key]
        else:
            info_od[key] = False
    frappe.db.sql("""
        INSERT INTO eBay_features_info (""" + ", ".join(info_od.keys()) + """)
            VALUES (""" + _s_for(info_od.values()) + """)
        """, info_od.values())

    # Set up the eBay_features_FeatureDefinitions table
    for fd in features_data['FeatureDefinitions']:
        if fd in FEATURES_NOT_SUPPORTED:
            continue
        extra = fd not in FEATURES_NOT_EXTRA
        frappe.db.sql("""
            INSERT INTO eBay_features_FeatureDefinitions
                (FeatureDefinition, Extra)
                VALUES (%s, %s)
            """, (fd, extra))

    # Set up the eBay_features_ListingDurations table
    for ld_key, tokens in features_data['ListingDurations'].items():
        if isinstance(tokens, six.string_types):
            tokens = (tokens,)
        for token in tokens:
            frappe.db.sql("""
                INSERT INTO eBay_features_ListingDurations
                    (durationSetID, ListingDurationToken)
                    VALUES (%s, %s)
                """, (ld_key, token))

    # Loop over categories, setting up the remaining tables
    cat_keys = FEATURES_BASE_COLUMNS

    # First set up the ROOT (CategoryID = 0) element with the SiteDefaults
    root_cat = features_data['SiteDefaults'].copy()
    root_cat['CategoryID'] = 0
    features_data['Category'].insert(0, root_cat)

    local_unsupported = []
    for cat in features_data['Category']:
        # OrderedDict to store values for main table
        cat_od = collections.OrderedDict()
        for key in cat_keys:
            cat_od[key] = None
        cat_id = cat['CategoryID']
        # Loop over attributes and values
        for key, value in cat.items():
            if key == 'ListingDuration':
                if not isinstance(value, collections.Sequence):
                    value = (value,)
                for ld_dict in value:
                    ld_key_str = 'ListingDuration' + ld_dict['_type']
                    cat_od[ld_key_str] = ld_dict['value']
            elif key == 'PaymentMethod':
                if isinstance(value, six.string_types):
                    value = (value,)
                for payment_method in value:
                    frappe.db.sql("""
                        INSERT INTO eBay_features_PaymentMethodConnections (
                            CategoryID, PaymentMethod )
                            VALUES (%s, %s)
                        """, (cat_id, payment_method))
            elif key == 'ConditionValues':
                if not isinstance(value, collections.Sequence):
                    value = (value,)
                for cv_dict in value:
                    frappe.db.sql("""
                        INSERT INTO eBay_features_ConditionValues (
                            CategoryID, ConditionID, DisplayName )
                            VALUES (%s, %s, %s)
                        """, (cat_id, cv_dict['ID'], cv_dict['DisplayName']))
            elif key == 'MaxFlatShippingCost':
                cat_od['MaxFlatShippingCostCurrency'] = value['_currencyID']
                cat_od['MaxFlatShippingCost'] = value['value']
            elif key in cat_keys:
                # This is one of the expected keys
                cat_od[key] = value
            else:
                # This is an 'extra' key
                if key in FEATURES_NOT_SUPPORTED:
                    continue
                if key in local_unsupported:
                    continue
                if (
                        not isinstance(value, six.string_types)
                        or len(key) > EBAY_ATTR_LEN
                        or len(value) > EBAY_VALUE_LEN):
                    print('Unsupported eBay attribute/value: {} : {}'.format(
                        key, value))
                    frappe.log(
                        'Unsupported eBay attribute/value: {} : {}'.format(
                            key, value))
                    local_unsupported.append(key)
                    raise ValueError('Fancy unsupported data type!')
                frappe.db.sql("""
                    INSERT INTO eBay_features_extra (
                        CategoryID, Attribute, Value )
                        VALUES (%s, %s, %s)
                """, (cat_id, key, value))

        # Insert the completed row for this category
        frappe.db.sql("""
            INSERT INTO eBay_features (""" + ", ".join(cat_od.keys()) + """)
                VALUES (""" + _s_for(cat_od.values()) + """)
            """, cat_od.values())

    frappe.db.commit()