<commit_before>import re
import warnings

class BadLineError(Exception):
    pass

class UnknownCodeError(Exception):
    pass

# The following files are used to talk to the HDF5 api:
#
# (1) hdf5.pxd:         HDF5 function signatures    (autogenerated)
# (2) hdf5_types.pxd:   HDF5 type definitions       (static)
# (3) defs.pxd:         HDF5 function proxy defs    (autogenerated)
# (4) defs.pyx:         HDF5 function proxies       (autogenerated)

function_pattern = r'([ ]+)?(?P<code>(unsigned[ ]+)?[a-zA-Z_]+[a-zA-Z0-9_]*\**)[ ]+(?P<fname>[a-zA-Z_]+[a-zA-Z0-9_]*)[ ]*\((?P<sig>[a-zA-Z0-9_,* ]*)\)'
sig_pattern = r'(unsigned[ ]+)?(?:[a-zA-Z_]+[a-zA-Z0-9_]*\**)[ ]+[ *]*(?P<param>[a-zA-Z_]+[a-zA-Z0-9_]*)'

fp = re.compile(function_pattern)
sp = re.compile(sig_pattern)

raw_preamble = """\
from api_types_hdf5 cimport *
from api_types_ext cimport *

"""

def_preamble = """\
from api_types_hdf5 cimport *
from api_types_ext cimport *

"""

imp_preamble = """\
from api_types_ext cimport *
from api_types_hdf5 cimport *

cimport _hdf5

from _errors cimport set_exception

"""

class FunctionCruncher2(object):

    def __init__(self, stub=False):
        self.stub = stub

    def run(self):

        # Function definitions file
        self.functions = open('api_functions.txt','r')

        # Create output files
        self.raw_defs =     open('_hdf5.pxd','w')
        self.cython_def =   open('defs.pxd','w')
        self.cython_imp =   open('defs.pyx','w')

        self.raw_defs.write(raw_preamble)
        self.cython_def.write(def_preamble)
        self.cython_imp.write(imp_preamble)

        for line in self.functions:
            if not line or line[0] == '#' or line[0] == '\n':
                continue
            try:
                self.handle_line(line)
            except BadLineError:
                warnings.warn("Skipped <<%s>>" % line)

        self.functions.close()
        self.cython_imp.close()
        self.cython_def.close()
        self.raw_defs.close()

    def handle_line(self, line):
        """ Parse a function definition line and output the correct code
        to each of the output files. """

        if line.startswith(' '):
            line = line.strip()
            if line.startswith('#'):
                return
            m = fp.match(line)
            if m is None:
                raise BadLineError(
                    "Signature for line <<%s>> did not match regexp" % line
                    )
            function_parts = m.groupdict()

            self.raw_defs.write('  '+self.make_raw_sig(function_parts))
            self.cython_def.write(self.make_cython_sig(function_parts))
            self.cython_imp.write(self.make_cython_imp(function_parts))
        else:
            inc = line.split(':')[0]
            self.raw_defs.write('cdef extern from "%s.h":\n' % inc)

    def make_raw_sig(self, function_parts):
        """ Build a "cdef extern"-style definition for an HDF5 function """

        return "%(code)s %(fname)s(%(sig)s)\n" % function_parts

    def make_cython_sig(self, function_parts):
        """ Build Cython signature for wrapper function """

        return "cdef %(code)s %(fname)s(%(sig)s) except *\n" % function_parts

    def make_cython_imp(self, function_parts, stub=False):
        """ Build a Cython wrapper implementation. If stub is True, do
        nothing but call the function and return its value """

        args = sp.findall(function_parts['sig'])
        if args is None:
            raise BadLineError("Can't understand function signature <<%s>>" % function_parts['sig'])
        args = ", ".join(x[1] for x in args)

        # Figure out what conditional to use for the error testing
        code = function_parts['code']
        if '*' in code or code in ('H5T_conv_t',):
            condition = "==NULL"
            retval = "NULL"
        elif code in ('int', 'herr_t', 'htri_t', 'hid_t','hssize_t','ssize_t') \
          or re.match(r'H5[A-Z]+_[a-zA-Z_]+_t',code):
            condition = "<0"
            retval = "-1"
        elif code in ('unsigned int','haddr_t','hsize_t','size_t'):
            condition = "==0"
            retval = 0
        else:
            raise UnknownCodeError("Return code <<%s>> unknown" % self.code)

        parts = function_parts.copy()
        parts.update({'condition': condition, 'retval': retval, 'args': args})

        # Have to use except * because Cython can't handle special types here
        imp = """\
cdef %(code)s %(fname)s(%(sig)s) except *:
    cdef %(code)s r
    r = _hdf5.%(fname)s(%(args)s)
    if r%(condition)s:
        if set_exception():
            return <%(code)s>%(retval)s;
    return r

"""

        stub_imp = """\
cdef %(code)s %(fname)s(%(sig)s) except *:
    return hdf5.%(fname)s(%(args)s)

"""
        return (stub_imp if self.stub else imp) % parts

if __name__ == '__main__':

    import sys
    stub = True if 'stub' in sys.argv else False
    fc = FunctionCruncher2(stub)
    fc.run()

<commit_msg>Add locking to prevent iteration deadlocks<commit_after>import re
import warnings

class BadLineError(Exception):
    pass

class UnknownCodeError(Exception):
    pass

# The following files are used to talk to the HDF5 api:
#
# (1) hdf5.pxd:         HDF5 function signatures    (autogenerated)
# (2) hdf5_types.pxd:   HDF5 type definitions       (static)
# (3) defs.pxd:         HDF5 function proxy defs    (autogenerated)
# (4) defs.pyx:         HDF5 function proxies       (autogenerated)

function_pattern = r'([ ]+)?(?P<code>(unsigned[ ]+)?[a-zA-Z_]+[a-zA-Z0-9_]*\**)[ ]+(?P<fname>[a-zA-Z_]+[a-zA-Z0-9_]*)[ ]*\((?P<sig>[a-zA-Z0-9_,* ]*)\)'
sig_pattern = r'(unsigned[ ]+)?(?:[a-zA-Z_]+[a-zA-Z0-9_]*\**)[ ]+[ *]*(?P<param>[a-zA-Z_]+[a-zA-Z0-9_]*)'

fp = re.compile(function_pattern)
sp = re.compile(sig_pattern)

raw_preamble = """\
from api_types_hdf5 cimport *
from api_types_ext cimport *

"""

def_preamble = """\
from api_types_hdf5 cimport *
from api_types_ext cimport *

"""

imp_preamble = """\
from api_types_ext cimport *
from api_types_hdf5 cimport *

cimport _hdf5

from _errors cimport set_exception

include "_locks.pxi"

rlock = FastRLock()
"""

class FunctionCruncher2(object):

    def __init__(self, stub=False):
        self.stub = stub

    def run(self):

        # Function definitions file
        self.functions = open('api_functions.txt','r')

        # Create output files
        self.raw_defs =     open('_hdf5.pxd','w')
        self.cython_def =   open('defs.pxd','w')
        self.cython_imp =   open('defs.pyx','w')

        self.raw_defs.write(raw_preamble)
        self.cython_def.write(def_preamble)
        self.cython_imp.write(imp_preamble)

        for line in self.functions:
            if not line or line[0] == '#' or line[0] == '\n':
                continue
            try:
                self.handle_line(line)
            except BadLineError:
                warnings.warn("Skipped <<%s>>" % line)

        self.functions.close()
        self.cython_imp.close()
        self.cython_def.close()
        self.raw_defs.close()

    def handle_line(self, line):
        """ Parse a function definition line and output the correct code
        to each of the output files. """

        if line.startswith(' '):
            line = line.strip()
            if line.startswith('#'):
                return
            m = fp.match(line)
            if m is None:
                raise BadLineError(
                    "Signature for line <<%s>> did not match regexp" % line
                    )
            function_parts = m.groupdict()

            self.raw_defs.write('  '+self.make_raw_sig(function_parts))
            self.cython_def.write(self.make_cython_sig(function_parts))
            self.cython_imp.write(self.make_cython_imp(function_parts))
        else:
            inc = line.split(':')[0]
            self.raw_defs.write('cdef extern from "%s.h":\n' % inc)

    def make_raw_sig(self, function_parts):
        """ Build a "cdef extern"-style definition for an HDF5 function """

        return "%(code)s %(fname)s(%(sig)s)\n" % function_parts

    def make_cython_sig(self, function_parts):
        """ Build Cython signature for wrapper function """

        return "cdef %(code)s %(fname)s(%(sig)s) except *\n" % function_parts

    def make_cython_imp(self, function_parts, stub=False):
        """ Build a Cython wrapper implementation. If stub is True, do
        nothing but call the function and return its value """

        args = sp.findall(function_parts['sig'])
        if args is None:
            raise BadLineError("Can't understand function signature <<%s>>" % function_parts['sig'])
        args = ", ".join(x[1] for x in args)

        # Figure out what conditional to use for the error testing
        code = function_parts['code']
        if '*' in code or code in ('H5T_conv_t',):
            condition = "==NULL"
            retval = "NULL"
        elif code in ('int', 'herr_t', 'htri_t', 'hid_t','hssize_t','ssize_t') \
          or re.match(r'H5[A-Z]+_[a-zA-Z_]+_t',code):
            condition = "<0"
            retval = "-1"
        elif code in ('unsigned int','haddr_t','hsize_t','size_t'):
            condition = "==0"
            retval = 0
        else:
            raise UnknownCodeError("Return code <<%s>> unknown" % self.code)

        parts = function_parts.copy()
        parts.update({'condition': condition, 'retval': retval, 'args': args})

        # Have to use except * because Cython can't handle special types here
        imp = """\
cdef %(code)s %(fname)s(%(sig)s) except *:
    cdef %(code)s r
    with rlock:
        r = _hdf5.%(fname)s(%(args)s)
        if r%(condition)s:
            if set_exception():
                return <%(code)s>%(retval)s;
        return r

"""

        stub_imp = """\
cdef %(code)s %(fname)s(%(sig)s) except *:
    with rlock:
        return hdf5.%(fname)s(%(args)s)

"""
        return (stub_imp if self.stub else imp) % parts

if __name__ == '__main__':

    import sys
    stub = True if 'stub' in sys.argv else False
    fc = FunctionCruncher2(stub)
    fc.run()

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt

from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from frappe.utils.data import now, nowdate, getdate, cint, add_days, date_diff, get_last_day, get_first_day
from frappe import _

SUBSCRIPTION_SETTINGS = frappe.get_single('Subscription Settings')

class Subscriptions(Document):
	def before_insert(self):
		# update start just before the subscription doc is created
		self.update_subscription_period()

	def update_subscription_period(self):
		self.set_current_invoice_start()
		self.set_current_invoice_end()

	def set_current_invoice_start(self, date=None):
		if self.trial_period_start and self.is_trialling():
			self.current_invoice_start = self.trial_period_start
		elif not date:
			current_invoice = self.get_current_invoice()
			if not current_invoice:
				self.current_invoice_start = nowdate()
			else:
				self.current_invoice_start = current_invoice.posting_date

	def set_current_invoice_end(self):
		if self.is_trialling():
			self.current_invoice_end = self.trial_period_end
		else:
			self.current_invoice_end = get_last_day(self.current_invoice_start)

	def before_save(self):
		self.set_status()

	def set_status(self):
		if self.is_trialling():
			self.status = 'Trialling'
		elif self.status == 'Past Due' and self.is_past_grace_period():
			self.status = 'Canceled' if cint(SUBSCRIPTION_SETTINGS.cancel_after_grace) else 'Unpaid'
		elif self.current_invoice_is_past_due():
			self.status = 'Past Due'
		elif self.is_new_subscription():
			self.status = 'Active'
			# todo: then generate new invoice

	def is_trialling(self):
		return not self.period_has_passed(self.trial_period_end) and self.is_new_subscription()

	def period_has_passed(self, end_date):
		# todo: test for illegal time
		if not end_date:
			return True

		end_date = getdate(end_date)
		return getdate(nowdate()) > getdate(end_date)

	def is_past_grace_period(self):
		current_invoice = self.get_current_invoice()
		if self.current_invoice_is_past_due(current_invoice):
			grace_period = cint(SUBSCRIPTION_SETTINGS.grace_period)

			return nowdate() > add_days(current_invoice.due_date, grace_period)

	def current_invoice_is_past_due(self, current_invoice=None):
		if not current_invoice:
			current_invoice = self.get_current_invoice()

		if not current_invoice:
			return False
		else:
			return getdate(nowdate()) > getdate(current_invoice.due_date)

	def get_current_invoice(self):
		if len(self.invoices):
			current = self.invoices[-1]
			doc = frappe.get_doc('Sales Invoice', current.invoice)
			return doc

	def is_new_subscription(self):
		return len(self.invoices) == 0

	def validate(self):
		self.validate_trial_period()

	def validate_trial_period(self):
		if self.trial_period_start and self.trial_period_end:
			if getdate(self.trial_period_end) < getdate(self.trial_period_start):
				frappe.throw(_('Trial Period End Date Cannot be before Trial Period Start Date'))

		elif self.trial_period_start or self.trial_period_end:
			frappe.throw(_('Both Trial Period Start Date and Trial Period End Date must be set'))

	def after_insert(self):
		if not self.is_trialling():
			self.generate_invoice()

	def generate_invoice(self):
		invoice = self.create_invoice()
		self.append('invoices', {'invoice': invoice.name})
		self.save()	# Validates all over again but we don't mind
		self.subscription_updated(invoice)

		return invoice

	def create_invoice(self):
		invoice = frappe.new_doc('Sales Invoice')
		invoice.customer = self.get_customer(self.subscriber)

		# Subscription is better suited for service items. I won't update `update_stock`
		# for that reason
		items_list = self.get_items_from_plans(self.plans)
		for item in items_list:
			item['qty'] = self.quantity
			invoice.append('items',	item)

		# Taxes
		# todo: tax template does not populate tax table
		if self.tax_template:
			invoice.taxes_and_charges = self.tax_template

		# Due date
		invoice.append(
			'payment_schedule',
			{
				'due_date': add_days(self.current_invoice_end, cint(self.days_until_due)),
				'invoice_portion': 100
			}
		)

		# Discounts
		if self.apply_additional_discount:
			invoice.apply_discount_on = self.apply_additional_discount

		if self.additional_discount_percentage:
			invoice.additional_discount_percentage = self.additional_discount_percentage

		if self.additional_discount_amount:
			invoice.additional_discount_amount = self.additional_discount_amount

		invoice.save()
		invoice.submit()

		return invoice

	def get_customer(self, subscriber_name):
		return frappe.get_value('Subscriber', subscriber_name)

	def get_items_from_plans(self, plans):
		plan_items = [plan.plan for plan in plans]

		if plan_items:
			item_names = frappe.db.sql(
				'select item as item_code, cost as rate from `tabSubscription Plan` where name in %s',
				(plan_items,), as_dict=1
			)
			return item_names

	def subscription_updated(self, invoice):
		self.update_subscription_period()
<commit_msg>refactor: - current_invoice _start and end should be determined by trial period or billing period - adds new functions to get billing period data<commit_after># -*- coding: utf-8 -*-
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt

from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from frappe.utils.data import now, nowdate, getdate, cint, add_days, date_diff, get_last_day, get_first_day, add_to_date
from frappe import _

SUBSCRIPTION_SETTINGS = frappe.get_single('Subscription Settings')

class Subscriptions(Document):
	def before_insert(self):
		# update start just before the subscription doc is created
		self.update_subscription_period()

	def update_subscription_period(self):
		self.set_current_invoice_start()
		self.set_current_invoice_end()

	def set_current_invoice_start(self, date=None):
		if self.trial_period_start and self.is_trialling():
			self.current_invoice_start = self.trial_period_start
		elif not date:
			self.current_invoice_start = nowdate()

	def set_current_invoice_end(self):
		if self.is_trialling():
			self.current_invoice_end = self.trial_period_end
		else:
			billing_cycle_info = self.get_billing_cycle()
			if billing_cycle_info:
				self.current_invoice_end = add_to_date(self.current_invoice_start, **billing_cycle_info)
			else:
				self.current_invoice_end = get_last_day(self.current_invoice_start)

	def get_billing_cycle(self):
		return self.get_billing_cycle_data()

	def validate_plans_billing_cycle(self, billing_cycle_data):
		if billing_cycle_data and len(billing_cycle_data) != 1:
			frappe.throw(_('You can only have Plans with the same billing cycle in a Subscription'))

	def get_billing_cycle_and_interval(self):
		plan_names = [plan.plan for plan in self.plans]
		billing_info = frappe.db.sql(
			'select distinct `billing_interval`, `billing_interval_count` '
			'from `tabSubscription Plan` '
			'where name in %s',
			(plan_names,), as_dict=1
		)

		return billing_info

	def get_billing_cycle_data(self):
		billing_info = self.get_billing_cycle_and_interval()

		self.validate_plans_billing_cycle(billing_info)

		if billing_info:
			data = dict()
			interval = billing_info[0]['billing_interval']
			interval_count = billing_info[0]['billing_interval_count']
			if interval not in ['Day', 'Week']:
				data['days'] = -1
			if interval == 'Day':
				data['days'] = interval_count - 1
			elif interval == 'Month':
				data['months'] = interval_count
			elif interval == 'Year':
				data['years'] == interval_count
			# todo: test week
			elif interval == 'Week':
				data['days'] = interval_count * 7 - 1

			return data

	def before_save(self):
		self.set_status()

	def set_status(self):
		if self.is_trialling():
			self.status = 'Trialling'
		elif self.status == 'Past Due' and self.is_past_grace_period():
			self.status = 'Canceled' if cint(SUBSCRIPTION_SETTINGS.cancel_after_grace) else 'Unpaid'
		elif self.current_invoice_is_past_due():
			self.status = 'Past Due'
		elif self.is_new_subscription():
			self.status = 'Active'
			# todo: then generate new invoice

	def is_trialling(self):
		return not self.period_has_passed(self.trial_period_end) and self.is_new_subscription()

	def period_has_passed(self, end_date):
		# todo: test for illegal time
		if not end_date:
			return True

		end_date = getdate(end_date)
		return getdate(nowdate()) > getdate(end_date)

	def is_past_grace_period(self):
		current_invoice = self.get_current_invoice()
		if self.current_invoice_is_past_due(current_invoice):
			grace_period = cint(SUBSCRIPTION_SETTINGS.grace_period)

			return nowdate() > add_days(current_invoice.due_date, grace_period)

	def current_invoice_is_past_due(self, current_invoice=None):
		if not current_invoice:
			current_invoice = self.get_current_invoice()

		if not current_invoice:
			return False
		else:
			return getdate(nowdate()) > getdate(current_invoice.due_date)

	def get_current_invoice(self):
		if len(self.invoices):
			current = self.invoices[-1]
			doc = frappe.get_doc('Sales Invoice', current.invoice)
			return doc

	def is_new_subscription(self):
		return len(self.invoices) == 0

	def validate(self):
		self.validate_trial_period()
		self.validate_plans_billing_cycle(self.get_billing_cycle_and_interval())

	def validate_trial_period(self):
		if self.trial_period_start and self.trial_period_end:
			if getdate(self.trial_period_end) < getdate(self.trial_period_start):
				frappe.throw(_('Trial Period End Date Cannot be before Trial Period Start Date'))

		elif self.trial_period_start or self.trial_period_end:
			frappe.throw(_('Both Trial Period Start Date and Trial Period End Date must be set'))

	def after_insert(self):
		if not self.is_trialling():
			self.generate_invoice()

	def generate_invoice(self):
		invoice = self.create_invoice()
		self.append('invoices', {'invoice': invoice.name})
		self.save()	# Validates all over again but we don't mind
		self.subscription_updated(invoice)

		return invoice

	def create_invoice(self):
		invoice = frappe.new_doc('Sales Invoice')
		invoice.customer = self.get_customer(self.subscriber)

		# Subscription is better suited for service items. I won't update `update_stock`
		# for that reason
		items_list = self.get_items_from_plans(self.plans)
		for item in items_list:
			item['qty'] = self.quantity
			invoice.append('items',	item)

		# Taxes
		# todo: tax template does not populate tax table
		if self.tax_template:
			invoice.taxes_and_charges = self.tax_template

		# Due date
		invoice.append(
			'payment_schedule',
			{
				'due_date': add_days(self.current_invoice_end, cint(self.days_until_due)),
				'invoice_portion': 100
			}
		)

		# Discounts
		if self.apply_additional_discount:
			invoice.apply_discount_on = self.apply_additional_discount

		if self.additional_discount_percentage:
			invoice.additional_discount_percentage = self.additional_discount_percentage

		if self.additional_discount_amount:
			invoice.additional_discount_amount = self.additional_discount_amount

		invoice.save()
		invoice.submit()

		return invoice

	def get_customer(self, subscriber_name):
		return frappe.get_value('Subscriber', subscriber_name)

	def get_items_from_plans(self, plans):
		plan_items = [plan.plan for plan in plans]

		if plan_items:
			item_names = frappe.db.sql(
				'select item as item_code, cost as rate from `tabSubscription Plan` where name in %s',
				(plan_items,), as_dict=1
			)
			return item_names

	def subscription_updated(self, invoice):
		self.update_subscription_period()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt

from __future__ import unicode_literals
import frappe, erpnext
from frappe import _
from frappe.model.document import Document
from frappe.utils import flt, nowdate
from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account

class EmployeeAdvanceOverPayment(frappe.ValidationError):
	pass

class EmployeeAdvance(Document):
	def onload(self):
		self.get("__onload").make_payment_via_journal_entry = frappe.db.get_single_value('Accounts Settings',
			'make_payment_via_journal_entry')

	def validate(self):
		self.set_status()
		self.validate_employee_advance_account()

	def on_cancel(self):
		self.set_status()

	def set_status(self):
		if self.docstatus == 0:
			self.status = "Draft"
		if self.docstatus == 1:
			if self.claimed_amount and flt(self.claimed_amount) == flt(self.paid_amount):
				self.status = "Claimed"
			elif self.paid_amount and self.advance_amount == flt(self.paid_amount):
				self.status = "Paid"
			else:
				self.status = "Unpaid"
		elif self.docstatus == 2:
			self.status = "Cancelled"

	def validate_employee_advance_account(self):
		company_currency = erpnext.get_company_currency(self.company)
		if (self.advance_account and
			company_currency != frappe.db.get_value('Account', self.advance_account, 'account_currency')):
			frappe.throw(_("Advance account currency should be same as company currency {0}")
				.format(company_currency))

	def set_total_advance_paid(self):
		paid_amount = frappe.db.sql("""
			select ifnull(sum(debit_in_account_currency), 0) as paid_amount
			from `tabGL Entry`
			where against_voucher_type = 'Employee Advance'
				and against_voucher = %s
				and party_type = 'Employee'
				and party = %s
		""", (self.name, self.employee), as_dict=1)[0].paid_amount

		return_amount = frappe.db.sql("""
			select name, ifnull(sum(credit_in_account_currency), 0) as return_amount
			from `tabGL Entry`
			where against_voucher_type = 'Employee Advance'
				and voucher_type != 'Expense Claim'
				and against_voucher = %s
				and party_type = 'Employee'
				and party = %s
		""", (self.name, self.employee), as_dict=1)[0].return_amount

		if flt(paid_amount) > self.advance_amount:
			frappe.throw(_("Row {0}# Paid Amount cannot be greater than requested advance amount"),
				EmployeeAdvanceOverPayment)

		if flt(return_amount) > self.paid_amount - self.claimed_amount:
			frappe.throw(_("Return amount cannot be greater unclaimed amount"))

		self.db_set("paid_amount", paid_amount)
		self.db_set("return_amount", return_amount)
		self.set_status()
		frappe.db.set_value("Employee Advance", self.name , "status", self.status)

	def update_claimed_amount(self):
		claimed_amount = frappe.db.sql("""
			SELECT sum(ifnull(allocated_amount, 0))
			FROM `tabExpense Claim Advance` eca, `tabExpense Claim` ec
			WHERE
				eca.employee_advance = %s
				AND ec.approval_status="Approved"
				AND ec.name = eca.parent
				AND ec.docstatus=1
				AND eca.allocated_amount > 0
		""", self.name)[0][0] or 0

		frappe.db.set_value("Employee Advance", self.name, "claimed_amount", flt(claimed_amount))
		self.reload()
		self.set_status()
		frappe.db.set_value("Employee Advance", self.name, "status", self.status)

@frappe.whitelist()
def get_due_advance_amount(employee, posting_date):
	employee_due_amount = frappe.get_all("Employee Advance", \
		filters = {"employee":employee, "docstatus":1, "posting_date":("<=", posting_date)}, \
		fields = ["advance_amount", "paid_amount"])
	return sum([(emp.advance_amount - emp.paid_amount) for emp in employee_due_amount])

@frappe.whitelist()
def make_bank_entry(dt, dn):
	doc = frappe.get_doc(dt, dn)
	payment_account = get_default_bank_cash_account(doc.company, account_type="Cash",
		mode_of_payment=doc.mode_of_payment)

	je = frappe.new_doc("Journal Entry")
	je.posting_date = nowdate()
	je.voucher_type = 'Bank Entry'
	je.company = doc.company
	je.remark = 'Payment against Employee Advance: ' + dn + '\n' + doc.purpose

	je.append("accounts", {
		"account": doc.advance_account,
		"debit_in_account_currency": flt(doc.advance_amount),
		"reference_type": "Employee Advance",
		"reference_name": doc.name,
		"party_type": "Employee",
		"party": doc.employee,
		"is_advance": "Yes"
	})

	je.append("accounts", {
		"account": payment_account.account,
		"credit_in_account_currency": flt(doc.advance_amount),
		"account_currency": payment_account.account_currency,
		"account_type": payment_account.account_type
	})

	return je.as_dict()

@frappe.whitelist()
def make_return_entry(employee, company, employee_advance_name,
		return_amount, advance_account, mode_of_payment=None):
	return_account = get_default_bank_cash_account(company, account_type='Cash', mode_of_payment = mode_of_payment)
	je = frappe.new_doc('Journal Entry')
	je.posting_date = nowdate()
	je.voucher_type = 'Bank Entry'
	je.company = company
	je.remark = 'Return against Employee Advance: ' + employee_advance_name

	je.append('accounts', {
		'account': advance_account,
		'credit_in_account_currency': return_amount,
		'reference_type': 'Employee Advance',
		'reference_name': employee_advance_name,
		'party_type': 'Employee',
		'party': employee,
		'is_advance': 'Yes'
	})

	je.append("accounts", {
		"account": return_account.account,
		"debit_in_account_currency": return_amount,
		"account_currency": return_account.account_currency,
		"account_type": return_account.account_type
	})

	return je.as_dict()

<commit_msg>fix: (ux) set jv voucher type depending on mode of payment (#21411)<commit_after># -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt

from __future__ import unicode_literals
import frappe, erpnext
from frappe import _
from frappe.model.document import Document
from frappe.utils import flt, nowdate
from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account

class EmployeeAdvanceOverPayment(frappe.ValidationError):
	pass

class EmployeeAdvance(Document):
	def onload(self):
		self.get("__onload").make_payment_via_journal_entry = frappe.db.get_single_value('Accounts Settings',
			'make_payment_via_journal_entry')

	def validate(self):
		self.set_status()
		self.validate_employee_advance_account()

	def on_cancel(self):
		self.set_status()

	def set_status(self):
		if self.docstatus == 0:
			self.status = "Draft"
		if self.docstatus == 1:
			if self.claimed_amount and flt(self.claimed_amount) == flt(self.paid_amount):
				self.status = "Claimed"
			elif self.paid_amount and self.advance_amount == flt(self.paid_amount):
				self.status = "Paid"
			else:
				self.status = "Unpaid"
		elif self.docstatus == 2:
			self.status = "Cancelled"

	def validate_employee_advance_account(self):
		company_currency = erpnext.get_company_currency(self.company)
		if (self.advance_account and
			company_currency != frappe.db.get_value('Account', self.advance_account, 'account_currency')):
			frappe.throw(_("Advance account currency should be same as company currency {0}")
				.format(company_currency))

	def set_total_advance_paid(self):
		paid_amount = frappe.db.sql("""
			select ifnull(sum(debit_in_account_currency), 0) as paid_amount
			from `tabGL Entry`
			where against_voucher_type = 'Employee Advance'
				and against_voucher = %s
				and party_type = 'Employee'
				and party = %s
		""", (self.name, self.employee), as_dict=1)[0].paid_amount

		return_amount = frappe.db.sql("""
			select name, ifnull(sum(credit_in_account_currency), 0) as return_amount
			from `tabGL Entry`
			where against_voucher_type = 'Employee Advance'
				and voucher_type != 'Expense Claim'
				and against_voucher = %s
				and party_type = 'Employee'
				and party = %s
		""", (self.name, self.employee), as_dict=1)[0].return_amount

		if flt(paid_amount) > self.advance_amount:
			frappe.throw(_("Row {0}# Paid Amount cannot be greater than requested advance amount"),
				EmployeeAdvanceOverPayment)

		if flt(return_amount) > self.paid_amount - self.claimed_amount:
			frappe.throw(_("Return amount cannot be greater unclaimed amount"))

		self.db_set("paid_amount", paid_amount)
		self.db_set("return_amount", return_amount)
		self.set_status()
		frappe.db.set_value("Employee Advance", self.name , "status", self.status)

	def update_claimed_amount(self):
		claimed_amount = frappe.db.sql("""
			SELECT sum(ifnull(allocated_amount, 0))
			FROM `tabExpense Claim Advance` eca, `tabExpense Claim` ec
			WHERE
				eca.employee_advance = %s
				AND ec.approval_status="Approved"
				AND ec.name = eca.parent
				AND ec.docstatus=1
				AND eca.allocated_amount > 0
		""", self.name)[0][0] or 0

		frappe.db.set_value("Employee Advance", self.name, "claimed_amount", flt(claimed_amount))
		self.reload()
		self.set_status()
		frappe.db.set_value("Employee Advance", self.name, "status", self.status)

@frappe.whitelist()
def get_due_advance_amount(employee, posting_date):
	employee_due_amount = frappe.get_all("Employee Advance", \
		filters = {"employee":employee, "docstatus":1, "posting_date":("<=", posting_date)}, \
		fields = ["advance_amount", "paid_amount"])
	return sum([(emp.advance_amount - emp.paid_amount) for emp in employee_due_amount])

@frappe.whitelist()
def make_bank_entry(dt, dn):
	doc = frappe.get_doc(dt, dn)
	payment_account = get_default_bank_cash_account(doc.company, account_type="Cash",
		mode_of_payment=doc.mode_of_payment)

	je = frappe.new_doc("Journal Entry")
	je.posting_date = nowdate()
	je.voucher_type = 'Bank Entry'
	je.company = doc.company
	je.remark = 'Payment against Employee Advance: ' + dn + '\n' + doc.purpose

	je.append("accounts", {
		"account": doc.advance_account,
		"debit_in_account_currency": flt(doc.advance_amount),
		"reference_type": "Employee Advance",
		"reference_name": doc.name,
		"party_type": "Employee",
		"party": doc.employee,
		"is_advance": "Yes"
	})

	je.append("accounts", {
		"account": payment_account.account,
		"credit_in_account_currency": flt(doc.advance_amount),
		"account_currency": payment_account.account_currency,
		"account_type": payment_account.account_type
	})

	return je.as_dict()

@frappe.whitelist()
def make_return_entry(employee, company, employee_advance_name,
		return_amount, advance_account, mode_of_payment=None):
	return_account = get_default_bank_cash_account(company, account_type='Cash', mode_of_payment = mode_of_payment)

	mode_of_payment_type = ''
	if mode_of_payment:
		mode_of_payment_type = frappe.get_cached_value('Mode of Payment', mode_of_payment, 'type')
		if mode_of_payment_type not in ["Cash", "Bank"]:
			# if mode of payment is General then it unset the type
			mode_of_payment_type = None

	je = frappe.new_doc('Journal Entry')
	je.posting_date = nowdate()
	# if mode of payment is Bank then voucher type is Bank Entry
	je.voucher_type = '{} Entry'.format(mode_of_payment_type) if mode_of_payment_type else 'Cash Entry'
	je.company = company
	je.remark = 'Return against Employee Advance: ' + employee_advance_name

	je.append('accounts', {
		'account': advance_account,
		'credit_in_account_currency': return_amount,
		'reference_type': 'Employee Advance',
		'reference_name': employee_advance_name,
		'party_type': 'Employee',
		'party': employee,
		'is_advance': 'Yes'
	})

	je.append("accounts", {
		"account": return_account.account,
		"debit_in_account_currency": return_amount,
		"account_currency": return_account.account_currency,
		"account_type": return_account.account_type
	})

	return je.as_dict()

<|endoftext|>


<commit_before>"""Const file for HassIO."""
from pathlib import Path

HASSIO_VERSION = '0.23'

URL_HASSIO_VERSION = ('https://raw.githubusercontent.com/home-assistant/'
                      'hassio/master/version.json')
URL_HASSIO_VERSION_BETA = ('https://raw.githubusercontent.com/home-assistant/'
                           'hassio/dev/version.json')

URL_HASSIO_ADDONS = 'https://github.com/home-assistant/hassio-addons'

DOCKER_REPO = "homeassistant"

HASSIO_SHARE = Path("/data")

RUN_UPDATE_INFO_TASKS = 28800
RUN_UPDATE_SUPERVISOR_TASKS = 29100
RUN_RELOAD_ADDONS_TASKS = 28800
RUN_WATCHDOG_HOMEASSISTANT = 15

RESTART_EXIT_CODE = 100

FILE_HASSIO_ADDONS = Path(HASSIO_SHARE, "addons.json")
FILE_HASSIO_CONFIG = Path(HASSIO_SHARE, "config.json")

SOCKET_DOCKER = Path("/var/run/docker.sock")
SOCKET_HC = Path("/var/run/hassio-hc.sock")

JSON_RESULT = 'result'
JSON_DATA = 'data'
JSON_MESSAGE = 'message'

RESULT_ERROR = 'error'
RESULT_OK = 'ok'

ATTR_ARCH = 'arch'
ATTR_HOSTNAME = 'hostname'
ATTR_OS = 'os'
ATTR_TYPE = 'type'
ATTR_SOURCE = 'source'
ATTR_FEATURES = 'features'
ATTR_ADDONS = 'addons'
ATTR_VERSION = 'version'
ATTR_LAST_VERSION = 'last_version'
ATTR_BETA_CHANNEL = 'beta_channel'
ATTR_NAME = 'name'
ATTR_SLUG = 'slug'
ATTR_DESCRIPTON = 'description'
ATTR_STARTUP = 'startup'
ATTR_BOOT = 'boot'
ATTR_PORTS = 'ports'
ATTR_MAP = 'map'
ATTR_OPTIONS = 'options'
ATTR_INSTALLED = 'installed'
ATTR_DETACHED = 'detached'
ATTR_STATE = 'state'
ATTR_SCHEMA = 'schema'
ATTR_IMAGE = 'image'
ATTR_ADDONS_REPOSITORIES = 'addons_repositories'
ATTR_REPOSITORY = 'repository'
ATTR_REPOSITORIES = 'repositories'
ATTR_URL = 'url'
ATTR_MAINTAINER = 'maintainer'

STARTUP_BEFORE = 'before'
STARTUP_AFTER = 'after'
STARTUP_ONCE = 'once'

BOOT_AUTO = 'auto'
BOOT_MANUAL = 'manual'

STATE_STARTED = 'started'
STATE_STOPPED = 'stopped'

MAP_CONFIG = 'config'
MAP_SSL = 'ssl'
MAP_ADDONS = 'addons'
MAP_BACKUP = 'backup'

ARCH_ARMHF = 'armhf'
ARCH_AARCH64 = 'aarch64'
ARCH_AMD64 = 'amd64'
ARCH_I386 = 'i386'
<commit_msg>Pump version to 0.24<commit_after>"""Const file for HassIO."""
from pathlib import Path

HASSIO_VERSION = '0.24'

URL_HASSIO_VERSION = ('https://raw.githubusercontent.com/home-assistant/'
                      'hassio/master/version.json')
URL_HASSIO_VERSION_BETA = ('https://raw.githubusercontent.com/home-assistant/'
                           'hassio/dev/version.json')

URL_HASSIO_ADDONS = 'https://github.com/home-assistant/hassio-addons'

DOCKER_REPO = "homeassistant"

HASSIO_SHARE = Path("/data")

RUN_UPDATE_INFO_TASKS = 28800
RUN_UPDATE_SUPERVISOR_TASKS = 29100
RUN_RELOAD_ADDONS_TASKS = 28800
RUN_WATCHDOG_HOMEASSISTANT = 15

RESTART_EXIT_CODE = 100

FILE_HASSIO_ADDONS = Path(HASSIO_SHARE, "addons.json")
FILE_HASSIO_CONFIG = Path(HASSIO_SHARE, "config.json")

SOCKET_DOCKER = Path("/var/run/docker.sock")
SOCKET_HC = Path("/var/run/hassio-hc.sock")

JSON_RESULT = 'result'
JSON_DATA = 'data'
JSON_MESSAGE = 'message'

RESULT_ERROR = 'error'
RESULT_OK = 'ok'

ATTR_ARCH = 'arch'
ATTR_HOSTNAME = 'hostname'
ATTR_OS = 'os'
ATTR_TYPE = 'type'
ATTR_SOURCE = 'source'
ATTR_FEATURES = 'features'
ATTR_ADDONS = 'addons'
ATTR_VERSION = 'version'
ATTR_LAST_VERSION = 'last_version'
ATTR_BETA_CHANNEL = 'beta_channel'
ATTR_NAME = 'name'
ATTR_SLUG = 'slug'
ATTR_DESCRIPTON = 'description'
ATTR_STARTUP = 'startup'
ATTR_BOOT = 'boot'
ATTR_PORTS = 'ports'
ATTR_MAP = 'map'
ATTR_OPTIONS = 'options'
ATTR_INSTALLED = 'installed'
ATTR_DETACHED = 'detached'
ATTR_STATE = 'state'
ATTR_SCHEMA = 'schema'
ATTR_IMAGE = 'image'
ATTR_ADDONS_REPOSITORIES = 'addons_repositories'
ATTR_REPOSITORY = 'repository'
ATTR_REPOSITORIES = 'repositories'
ATTR_URL = 'url'
ATTR_MAINTAINER = 'maintainer'

STARTUP_BEFORE = 'before'
STARTUP_AFTER = 'after'
STARTUP_ONCE = 'once'

BOOT_AUTO = 'auto'
BOOT_MANUAL = 'manual'

STATE_STARTED = 'started'
STATE_STOPPED = 'stopped'

MAP_CONFIG = 'config'
MAP_SSL = 'ssl'
MAP_ADDONS = 'addons'
MAP_BACKUP = 'backup'

ARCH_ARMHF = 'armhf'
ARCH_AARCH64 = 'aarch64'
ARCH_AMD64 = 'amd64'
ARCH_I386 = 'i386'
<|endoftext|>


<commit_before>__version__ = '0.6.1'
<commit_msg>bump version<commit_after>__version__ = '0.6.2'
<|endoftext|>


<commit_before># Project: finmarketpy project
# Filename: learn_network_structure
# Objective: compute a network graph for a group of asset return time series
# Created: 2019-11-02 12:05
# Version: 0.0
# Author: FS

# importing packages
import numpy as np
# import pandas as pd

# import matplotlib.pyplot as plt
# from matplotlib.collections import LineCollection

from sklearn import cluster, covariance, manifold

def learn_network_structure(ts_returns_data, names, alphas=4, cv=5, mode='cd',
							assume_centered = False,
							n_components=2, n_neighbors=5,
							eigen_solver="dense", method='standard',
							neighbors_algorithm="auto",
							random_state = None, n_jobs=None,
							standardise=False):
	"""

	Parameters
	----------
	ts_returns_data : array-like of shape [n_samples, n_instruments]
	                  return time series matrix

	names : array-like of shape [n_samples, 1]
	        individual names of the financial instrument

	alphas : int or positive float, optional
	         number of points on the grids to be used

	cv : int, optional
	     number of folds for cross-validation splitting strategy

	mode : str, optional
	       solver to use to compute the graph

	assume_centered : bool, optional
                      centre the data if False.

	n_components : int
	               number of components for the manifold

	n_neighbors: int
                 number of neighbours to consider for each point

	eigen_solver : str
	               algorithm to compute eigenvalues

	method : str
             algorithm to use for local linear embedding
	neighbors_algorithm : str
	                      algorithm to use for nearest neighbours search

	random_state : int, RandomState instance or None, optional
	               If int, random_state is the seed used by the random number generator.
	               If RandomState instance, random_state is the random number generator.
	               If None, the random number generator is the RandomState instance used by np.random.
	               Used when eigen_solver == ‘arpack’

	n_jobs : int or None, optional
	         number of parallel jobs to run

	standardise : bool
	              standardise data if True

	Returns : sklearn.covariance.graph_lasso_.GraphicalLassoCV

              sklearn.manifold.locally_linear.LocallyLinearEmbedding

              array-like of shape [n_components, n_instruments]

	-------
	"""

	if not isinstance(ts_returns_data, (np.ndarray, np.generic)):
		raise TypeError("ts_returns_data must be of class ndarray")

	# learn graphical structure
	edge_model = covariance.GraphicalLassoCV(alphas=alphas, cv=cv, mode=mode,
											 assume_centered=assume_centered)
	edge_model.fit(ts_returns_data)

	# cluster using affinity propagation
	_, labels = cluster.affinity_propagation(edge_model.covariance_)
	n_labels = labels.max()
	for i in range(n_labels + 1):
		print('Cluster %i: %s' % ((i + 1), ', '.join(names[labels == i])))

	# find low-dimension embedding - useful for 2D plane visualisation
	node_position_model = manifold.LocallyLinearEmbedding(
			n_components=n_components, eigen_solver=eigen_solver,
			n_neighbors=n_neighbors, method=method,
			neighbors_algorithm=neighbors_algorithm,
			random_state=random_state, n_jobs=n_jobs)
	embedding = node_position_model.fit_transform(ts_returns_data.T).T

	if standardise:
		# standardise returns
		standard_ret = ts_returns_data.copy()
		standard_ret /= ts_returns_data.std(axis=0)

		# learn graph model
		edge_model.fit(standard_ret)

		# cluster using affinity propagation
		_, labels = cluster.affinity_propagation(edge_model.covariance_)
		n_labels = labels.max()
		for i in range(n_labels + 1):
			print('Cluster %i: %s' % ((i + 1), ', '.join(names[labels == i])))

		# find low-dimension embedding - useful for 2D plane visualisation
		node_position_model = manifold.LocallyLinearEmbedding(
				n_components=n_components, eigen_solver=eigen_solver,
				n_neighbors=n_neighbors, method=method,
				neighbors_algorithm=neighbors_algorithm,
				random_state=random_state, n_jobs=n_jobs)
		embedding = node_position_model.fit_transform(ts_returns_data.T).T

	return edge_model, node_position_model, embedding
<commit_msg>Method now returns a numeric identifier for each cluster. Useful when visualising the network.<commit_after># Project: finmarketpy project
# Filename: learn_network_structure
# Objective: compute a network graph for a group of asset return time series
# Created: 2019-11-02 12:05
# Version: 0.0
# Author: FS

# importing packages
import numpy as np
from sklearn import cluster, covariance, manifold

def learn_network_structure(ts_returns_data, names, alphas=4, cv=5, mode='cd',
							assume_centered = False,
							n_components=2, n_neighbors=5,
							eigen_solver="dense", method='standard',
							neighbors_algorithm="auto",
							random_state = None, n_jobs=None,
							standardise=False):
	"""

	Parameters
	----------
	ts_returns_data : array-like of shape [n_samples, n_instruments]
	                  time series matrix of returns

	names : array-like of shape [n_samples, 1]
	        Individual names of the financial instrument

	alphas : int or positive float, optional
	         Number of points on the grids to be used

	cv : int, optional
	     Number of folds for cross-validation splitting strategy

	mode : str, optional
	       Solver to use to compute the graph

	assume_centered : bool, optional
                      Centre the data if False.

	n_components : int
	               Number of components for the manifold

	n_neighbors: int
                 Number of neighbours to consider for each point

	eigen_solver : str
	               Algorithm to compute eigenvalues

	method : str
             Algorithm to use for local linear embedding
	neighbors_algorithm : str
	                      Algorithm to use for nearest neighbours search

	random_state : int, RandomState instance or None, optional
	               If int, random_state is the seed used by the random number generator.
	               If RandomState instance, random_state is the random number generator.
	               If None, the random number generator is the RandomState instance used by np.random.
	               Used when eigen_solver == ‘arpack’

	n_jobs : int or None, optional
	         number of parallel jobs to run

	standardise : bool
	              standardise data if True

	Returns : sklearn.covariance.graph_lasso_.GraphicalLassoCV

              sklearn.manifold.locally_linear.LocallyLinearEmbedding

              array-like of shape [n_components, n_instruments]
              Transformed embedding vectors

              array-like of shape [n_instruments, 1]
              numeric identifier of each cluster

	-------
	"""

	if not isinstance(ts_returns_data, (np.ndarray, np.generic)):
		raise TypeError("ts_returns_data must be of class ndarray")

	# learn graphical structure
	edge_model = covariance.GraphicalLassoCV(alphas=alphas, cv=cv, mode=mode,
											 assume_centered=assume_centered)
	edge_model.fit(ts_returns_data)

	# cluster using affinity propagation
	_, labels = cluster.affinity_propagation(edge_model.covariance_)
	n_labels = labels.max()
	for i in range(n_labels + 1):
		print('Cluster %i: %s' % ((i + 1), ', '.join(names[labels == i])))

	# find low-dimension embedding - useful for 2D plane visualisation
	node_position_model = manifold.LocallyLinearEmbedding(
			n_components=n_components, eigen_solver=eigen_solver,
			n_neighbors=n_neighbors, method=method,
			neighbors_algorithm=neighbors_algorithm,
			random_state=random_state, n_jobs=n_jobs)
	embedding = node_position_model.fit_transform(ts_returns_data.T).T

	if standardise:
		# standardise returns
		standard_ret = ts_returns_data.copy()
		standard_ret /= ts_returns_data.std(axis=0)

		# learn graph model
		edge_model.fit(standard_ret)

		# cluster using affinity propagation
		_, labels = cluster.affinity_propagation(edge_model.covariance_)
		n_labels = labels.max()
		for i in range(n_labels + 1):
			print('Cluster %i: %s' % ((i + 1), ', '.join(names[labels == i])))

		# find low-dimension embedding - useful for 2D plane visualisation
		node_position_model = manifold.LocallyLinearEmbedding(
				n_components=n_components, eigen_solver=eigen_solver,
				n_neighbors=n_neighbors, method=method,
				neighbors_algorithm=neighbors_algorithm,
				random_state=random_state, n_jobs=n_jobs)
		embedding = node_position_model.fit_transform(ts_returns_data.T).T

	return edge_model, node_position_model, embedding, labels
<|endoftext|>


<commit_before>from __future__ import unicode_literals, division, absolute_import
import logging
from datetime import datetime
import re

from flexget import plugin
from flexget.event import event

try:
    # TODO implement TVMaze API internally
    from pytvmaze import get_show, lookup_tvrage, lookup_tvdb
except ImportError as e:
    raise plugin.PluginError('Could not import from pytvmaze')

log = logging.getLogger('est_series_tvmaze')

class EstimatesSeriesTVMaze(object):
    @plugin.priority(2)
    def estimate(self, entry):
        if not all(field in entry for field in ['series_name', 'series_season', 'series_episode']):
            return
        series_name = re.sub('[()]', '', entry['series_name'])  # Remove parenthesis from year if present
        season = entry['series_season']
        episode_number = entry['series_episode']
        log.debug('Search TVMaze for show %s' % series_name)
        if entry.get('tvdb_id'):
            tvmaze_show = lookup_tvdb(entry.get('tvdb_id'))
        elif entry.get('tvrage_id'):
            tvmaze_show = lookup_tvdb(entry.get('tvrage_id'))
        else:
            tvmaze_show = get_show(series_name)
        if not tvmaze_show:
            log.debug('TVMaze did not find match for %s' % series_name)
            return
        episode = tvmaze_show[season][episode_number]
        if episode:
            return datetime.strptime(episode.airdate, '%Y-%m-%d')
        else:
            log.debug('No episode info obtained from TVMaze for %s season %s episode %s' % (
                entry['series_name'], entry['series_season'], entry['series_episode']))
        return

@event('plugin.register')
def register_plugin():
    plugin.register(EstimatesSeriesTVMaze, 'est_series_tvmaze', groups=['estimate_release'], api_ver=2)
<commit_msg>Fixed get show by tvdb_id, tvrage_id or maze_id if present in entry<commit_after>from __future__ import unicode_literals, division, absolute_import
import logging
from datetime import datetime
import re

from flexget import plugin
from flexget.event import event

try:
    # TODO implement TVMaze API internally
    from pytvmaze import get_show, lookup_tvrage, lookup_tvdb
except ImportError as e:
    raise plugin.PluginError('Could not import from pytvmaze')

log = logging.getLogger('est_series_tvmaze')

class EstimatesSeriesTVMaze(object):
    @plugin.priority(2)
    def estimate(self, entry):
        if not all(field in entry for field in ['series_name', 'series_season', 'series_episode']):
            return
        series_name = re.sub('[()]', '', entry['series_name'])  # Remove parenthesis from year if present
        season = entry['series_season']
        episode_number = entry['series_episode']
        log.debug('Search TVMaze for show %s' % series_name)
        if entry.get('maze_id'):
            tvmaze_show = get_show(int(entry.get('maze_id')))
        elif entry.get('tvdb_id'):
            tvmaze_show = get_show(int(lookup_tvdb(entry.get('tvdb_id'))['id']))
        elif entry.get('tvrage_id'):
            tvmaze_show = get_show(int(lookup_tvdb(entry.get('tvrage_id'))['id']))
        else:
            tvmaze_show = get_show(series_name)
        if not tvmaze_show:
            log.debug('TVMaze did not find match for %s' % series_name)
            return
        episode = tvmaze_show[season][episode_number]
        if episode:
            return datetime.strptime(episode.airdate, '%Y-%m-%d')
        else:
            log.debug('No episode info obtained from TVMaze for %s season %s episode %s' % (
                entry['series_name'], entry['series_season'], entry['series_episode']))
        return

@event('plugin.register')
def register_plugin():
    plugin.register(EstimatesSeriesTVMaze, 'est_series_tvmaze', groups=['estimate_release'], api_ver=2)
<|endoftext|>


<commit_before># author: G. Alomar
import uuid
from collections import Iterable
from collections import namedtuple

import logging
from types import NoneType

from hfetch import Hcache

from IStorage import IStorage
from hecuba import config, log

class NamedIterator:
    def __init__(self, hiterator, builder):
        self.hiterator = hiterator
        self.builder = builder

    def __iter__(self):
        return self

    def next(self):
        n = self.hiterator.get_next()
        if self.builder is not None:
            return self.builder(*n)
        else:
            return n[0]

class NamedItemsIterator:
    builder = namedtuple('row', 'key, value')

    def __init__(self, key_builder, column_builder, k_size, hiterator):
        self.key_builder = key_builder
        self.k_size = k_size
        self.column_builder = column_builder
        self.hiterator = hiterator

    def __iter__(self):
        return self

    def next(self):
        n = self.hiterator.get_next()
        if self.key_builder is None:
            k = n[0]
        else:
            k = self.key_builder(*n[0:self.k_size])
        if self.column_builder is None:
            v = n[self.k_size]
        else:
            v = self.column_builder(*n[self.k_size:])
        return self.builder(k, v)

class StorageDict(dict, IStorage):
    """
    Object used to access data from workers.
    """

    args_names = ["primary_keys", "columns", "name", "tokens", "storage_id"]
    args = namedtuple('StorageDictArgs', args_names)
    _prepared_store_meta = config.session.prepare('INSERT INTO hecuba.istorage (storage_id, class_name,'
                                                  ' name, tokens,dict_pks,dict_columns)  VALUES (?,?,?,?,?,?)')

    @staticmethod
    def build_remotely(result):
        """
        Launches the Block.__init__ from the api.getByID
        Args:
            result: a namedtuple with all  the information needed to create again the block
        """

        return StorageDict(result.primary_keys,
                           result.columns,
                           result.name,
                           result.tokens
                           )

    @staticmethod
    def _store_meta(storage_args):
        class_name = '%s.%s' % (StorageDict.__class__.__module__, StorageDict.__class__.__name__)

        try:
            config.session.execute(StorageDict._prepared_store_meta,
                                   [storage_args.storage_id, class_name, storage_args.name,
                                    storage_args.tokens, storage_args.primary_keys, storage_args.columns])
        except Exception as ex:
            log.error("Error creating the StorageDict metadata: %s %s", storage_args, ex)
            raise ex

    def __init__(self, primary_keys, columns, name=None, tokens=None, **kwargs):
        """
        Creates a new block.

        Args:
            table_name (string): the name of the collection/table
            keyspace_name (string): name of the Cassandra keyspace.
            primary_keys (list(tuple)): a list of (key,type) primary keys (primary + clustering).
            columns (list(tuple)): a list of (key,type) columns
            tokens (list): list of tokens
            storage_id (string): the storage id identifier
        """

        super(StorageDict, self).__init__(**kwargs)
        log.debug("CREATED StorageDict(%s,%s,%s,%s,%s)", primary_keys, columns, name, tokens, kwargs)

        if tokens is None:
            log.info('using all tokens')
            tokens = map(lambda a: a.value, config.cluster.metadata.token_map.ring)
            tokens.sort()
            self.tokens = []
            n_tns = len(tokens)
            for i in range(0, n_tns):
                self.tokens.append((tokens[i], tokens[(i + 1) % n_tns]))
        else:
            self.tokens = tokens

        self._build_args = self.args(primary_keys, columns, name, self.tokens, None)
        self._primary_keys = primary_keys
        self._columns = columns

        self.values = columns
        key_names = map(lambda a: a[0], self._primary_keys)
        column_names = map(lambda a: a[0], self._columns)
        self._item_builder = namedtuple('row', map(lambda a: a[0], primary_keys + columns))

        if len(key_names) > 1:
            self._key_builder = namedtuple('row', key_names)
        else:
            self._key_builder = None
        if len(column_names) > 1:
            self._column_builder = namedtuple('row', column_names)
        else:
            self._column_builder = None

        self._k_size = len(key_names)

        if name is not None:
            self.make_persistent(name)
        else:
            self._is_persistent = False

    def __eq__(self, other):
        return self.dict_id == other.blockid and \
               self.tokens == other.token_ranges \
               and self._table == other.table_name and self._ksp == other.keyspace

    def __contains__(self, key):
        if not self._is_persistent:
            return dict.__contains__(self, key)
        else:
            try:
                self._hcache.get_row(self._make_key(key))
                return True
            except Exception as e:
                print "Exception in persistentDict.__contains__:", e
                return False

    def _make_key(self, key):
        if isinstance(key, str) or not isinstance(key, Iterable):
            if len(self._primary_keys) == 1:
                return [key]
            else:
                raise Exception('missing a primary key')

        if isinstance(key, Iterable) and len(key) == len(self._primary_keys):
            return list(key)
        else:
            raise Exception('wrong primary key')

    @staticmethod
    def _make_value(key):
        if isinstance(key, str) or not isinstance(key, Iterable):
            return [key]
        else:
            return list(key)

    def keys(self):
        """
        This method return a list of all the keys of the PersistentDict.
        Returns:
          list: a list of keys
        """
        return [i for i in self.iterkeys()]

    def __iter__(self):
        return self.iterkeys()

    def make_persistent(self, name):
        (self._ksp, self._table) = self._extract_ks_tab(name)
        self._build_args = self._build_args._replace(name=name)

        if not hasattr(self, 'storage_id'):
            self.storage_id = str(uuid.uuid1())
            self._build_args = self._build_args._replace(storage_id=self.storage_id)

        query_keyspace = "CREATE KEYSPACE IF NOT EXISTS %s WITH replication = {'class': 'SimpleStrategy'," \
                         "'replication_factor': %d }" % (self._ksp, config.repl_factor)
        try:
            config.session.execute(query_keyspace)
        except Exception as ex:
            print "Error creating the StorageDict keyspace:", query_keyspace, ex
            raise ex

        columns = map(lambda a: a[0] + " " + a[1], self._primary_keys + self._columns)
        pks = map(lambda a: a[0], self._primary_keys)
        query_table = "CREATE TABLE IF NOT EXISTS %s.%s (%s, PRIMARY KEY (%s));" % (self._ksp, self._table,
                                                                                str.join(',', columns),
                                                                                str.join(',', pks))
        log.debug('MAKE PERSISTENCE: %s', query_table)
        try:
            config.session.execute(query_table)
        except Exception as ex:
            log.error("Error creating the StorageDict table: %s %s", query_table, ex)
            raise ex

        self._store_meta(self._build_args)
        key_names = map(lambda a: a[0], self._primary_keys)
        column_names = map(lambda a: a[0], self._columns)
        tknp = "token(%s)" % key_names[0]
        self._hcache_params = (config.max_cache_size, self._ksp, self._table,
                               "WHERE %s>=? AND %s<?;" % (tknp, tknp),
                               self.tokens, key_names, column_names)
        log.debug("HCACHE params %s", self._hcache_params)
        self._hcache = Hcache(*self._hcache_params)
        # Storing all in-memory values to cassandra
        for key, value in dict.iteritems(self):
            self._hcache.put_row(self._make_key(key), self._make_value(value))
        self._is_persistent = True

    def stop_persistent(self):
        self._is_persistent = True
        self._hcache = None

    def delete_persistent(self):
        self.stop_persistent()
        query = "TRUNCATE TABLE %s.%s;" % (self._ksp, self._table)
        log.debug('DELETE PERSISTENCE: %s', query)
        config.session.execute(query)

    def __getitem__(self, key):
        """
        If the object is persistent, each request goes to the prefetcher.
        Args:
             key: the dictionary key
        Returns
             item: value found in position key
        """
        log.debug('GET ITEM %s', key)

        if not self._is_persistent:
            return dict.__getitem__(self, key)

        else:
            cres = self._hcache.get_row(self._make_key(key))
            log.debug("GET ITEM %s[%s]", cres, cres.__class__)

            if issubclass(cres.__class__, NoneType):
                return None
            elif self._column_builder is not None:
                return self._column_builder(cres)
            else:
                return cres

    def __setitem__(self, key, val):
        """
           Launches the setitem of the dict found in the block storageobj
           Args:
               key: the position of the value that we want to save
               val: the value that we want to save in that position
           Returns:
        """
        log.debug('SET ITEM %s->%s', key, val)
        if not self._is_persistent:
            dict.__setitem__(self, key, val)
        else:
            self._hcache.put_row(self._make_key(key), self._make_value(val))

    def getID(self):
        """
        Obtains the id of the block
        Returns:
            self.blockid: id of the block
        """
        return self.dict_id

    def iterkeys(self):
        """
        Obtains the iterator for the keys of the block
        Returns:
            iterkeys(self): list of keys
        """
        if self._is_persistent:
            ik = self._hcache.iterkeys(config.prefetch_size)
            return NamedIterator(ik, self._key_builder)
        else:
            return dict.iterkeys(self)

    def iteritems(self):
        """
        Obtains the iterator for the key,val pairs of the block
        Returns:
            BlockItemsIter(self): list of key,val pairs
        """
        if self._is_persistent:
            ik = self._hcache.iteritems(config.prefetch_size)
            return NamedItemsIterator(self._key_builder, self._column_builder, self._k_size, ik)
        else:
            return dict.iteritems(self)

    def itervalues(self):
        """
        Obtains the iterator for the values of the block
        Returns:
            BlockValuesIter(self): list of values
        """
        if self._is_persistent:
            ik = self._hcache.itervalues(config.prefetch_size)
            return NamedIterator(ik, self._column_builder)
        else:
            return dict.itervalues(self)
<commit_msg>stop !=delete<commit_after># author: G. Alomar
import uuid
from collections import Iterable
from collections import namedtuple

import logging
from types import NoneType

from hfetch import Hcache

from IStorage import IStorage
from hecuba import config, log

class NamedIterator:
    def __init__(self, hiterator, builder):
        self.hiterator = hiterator
        self.builder = builder

    def __iter__(self):
        return self

    def next(self):
        n = self.hiterator.get_next()
        if self.builder is not None:
            return self.builder(*n)
        else:
            return n[0]

class NamedItemsIterator:
    builder = namedtuple('row', 'key, value')

    def __init__(self, key_builder, column_builder, k_size, hiterator):
        self.key_builder = key_builder
        self.k_size = k_size
        self.column_builder = column_builder
        self.hiterator = hiterator

    def __iter__(self):
        return self

    def next(self):
        n = self.hiterator.get_next()
        if self.key_builder is None:
            k = n[0]
        else:
            k = self.key_builder(*n[0:self.k_size])
        if self.column_builder is None:
            v = n[self.k_size]
        else:
            v = self.column_builder(*n[self.k_size:])
        return self.builder(k, v)

class StorageDict(dict, IStorage):
    """
    Object used to access data from workers.
    """

    args_names = ["primary_keys", "columns", "name", "tokens", "storage_id"]
    args = namedtuple('StorageDictArgs', args_names)
    _prepared_store_meta = config.session.prepare('INSERT INTO hecuba.istorage (storage_id, class_name,'
                                                  ' name, tokens,dict_pks,dict_columns)  VALUES (?,?,?,?,?,?)')

    @staticmethod
    def build_remotely(result):
        """
        Launches the Block.__init__ from the api.getByID
        Args:
            result: a namedtuple with all  the information needed to create again the block
        """

        return StorageDict(result.primary_keys,
                           result.columns,
                           result.name,
                           result.tokens
                           )

    @staticmethod
    def _store_meta(storage_args):
        class_name = '%s.%s' % (StorageDict.__class__.__module__, StorageDict.__class__.__name__)

        try:
            config.session.execute(StorageDict._prepared_store_meta,
                                   [storage_args.storage_id, class_name, storage_args.name,
                                    storage_args.tokens, storage_args.primary_keys, storage_args.columns])
        except Exception as ex:
            log.error("Error creating the StorageDict metadata: %s %s", storage_args, ex)
            raise ex

    def __init__(self, primary_keys, columns, name=None, tokens=None, **kwargs):
        """
        Creates a new block.

        Args:
            table_name (string): the name of the collection/table
            keyspace_name (string): name of the Cassandra keyspace.
            primary_keys (list(tuple)): a list of (key,type) primary keys (primary + clustering).
            columns (list(tuple)): a list of (key,type) columns
            tokens (list): list of tokens
            storage_id (string): the storage id identifier
        """

        super(StorageDict, self).__init__(**kwargs)
        log.debug("CREATED StorageDict(%s,%s,%s,%s,%s)", primary_keys, columns, name, tokens, kwargs)

        if tokens is None:
            log.info('using all tokens')
            tokens = map(lambda a: a.value, config.cluster.metadata.token_map.ring)
            tokens.sort()
            self.tokens = []
            n_tns = len(tokens)
            for i in range(0, n_tns):
                self.tokens.append((tokens[i], tokens[(i + 1) % n_tns]))
        else:
            self.tokens = tokens

        self._build_args = self.args(primary_keys, columns, name, self.tokens, None)
        self._primary_keys = primary_keys
        self._columns = columns

        self.values = columns
        key_names = map(lambda a: a[0], self._primary_keys)
        column_names = map(lambda a: a[0], self._columns)
        self._item_builder = namedtuple('row', map(lambda a: a[0], primary_keys + columns))

        if len(key_names) > 1:
            self._key_builder = namedtuple('row', key_names)
        else:
            self._key_builder = None
        if len(column_names) > 1:
            self._column_builder = namedtuple('row', column_names)
        else:
            self._column_builder = None

        self._k_size = len(key_names)

        if name is not None:
            self.make_persistent(name)
        else:
            self._is_persistent = False

    def __eq__(self, other):
        return self.dict_id == other.blockid and \
               self.tokens == other.token_ranges \
               and self._table == other.table_name and self._ksp == other.keyspace

    def __contains__(self, key):
        if not self._is_persistent:
            return dict.__contains__(self, key)
        else:
            try:
                self._hcache.get_row(self._make_key(key))
                return True
            except Exception as e:
                print "Exception in persistentDict.__contains__:", e
                return False

    def _make_key(self, key):
        if isinstance(key, str) or not isinstance(key, Iterable):
            if len(self._primary_keys) == 1:
                return [key]
            else:
                raise Exception('missing a primary key')

        if isinstance(key, Iterable) and len(key) == len(self._primary_keys):
            return list(key)
        else:
            raise Exception('wrong primary key')

    @staticmethod
    def _make_value(key):
        if isinstance(key, str) or not isinstance(key, Iterable):
            return [key]
        else:
            return list(key)

    def keys(self):
        """
        This method return a list of all the keys of the PersistentDict.
        Returns:
          list: a list of keys
        """
        return [i for i in self.iterkeys()]

    def __iter__(self):
        return self.iterkeys()

    def make_persistent(self, name):
        (self._ksp, self._table) = self._extract_ks_tab(name)
        self._build_args = self._build_args._replace(name=name)

        if not hasattr(self, 'storage_id'):
            self.storage_id = str(uuid.uuid1())
            self._build_args = self._build_args._replace(storage_id=self.storage_id)

        query_keyspace = "CREATE KEYSPACE IF NOT EXISTS %s WITH replication = {'class': 'SimpleStrategy'," \
                         "'replication_factor': %d }" % (self._ksp, config.repl_factor)
        try:
            config.session.execute(query_keyspace)
        except Exception as ex:
            print "Error creating the StorageDict keyspace:", query_keyspace, ex
            raise ex

        columns = map(lambda a: a[0] + " " + a[1], self._primary_keys + self._columns)
        pks = map(lambda a: a[0], self._primary_keys)
        query_table = "CREATE TABLE IF NOT EXISTS %s.%s (%s, PRIMARY KEY (%s));" % (self._ksp, self._table,
                                                                                str.join(',', columns),
                                                                                str.join(',', pks))
        log.debug('MAKE PERSISTENCE: %s', query_table)
        try:
            config.session.execute(query_table)
        except Exception as ex:
            log.error("Error creating the StorageDict table: %s %s", query_table, ex)
            raise ex

        self._store_meta(self._build_args)
        key_names = map(lambda a: a[0], self._primary_keys)
        column_names = map(lambda a: a[0], self._columns)
        tknp = "token(%s)" % key_names[0]
        self._hcache_params = (config.max_cache_size, self._ksp, self._table,
                               "WHERE %s>=? AND %s<?;" % (tknp, tknp),
                               self.tokens, key_names, column_names)
        log.debug("HCACHE params %s", self._hcache_params)
        self._hcache = Hcache(*self._hcache_params)
        # Storing all in-memory values to cassandra
        for key, value in dict.iteritems(self):
            self._hcache.put_row(self._make_key(key), self._make_value(value))
        self._is_persistent = True

    def stop_persistent(self):
        self._is_persistent = True
        self._hcache = None

    def delete_persistent(self):
        query = "TRUNCATE TABLE %s.%s;" % (self._ksp, self._table)
        log.debug('DELETE PERSISTENCE: %s', query)
        config.session.execute(query)

    def __getitem__(self, key):
        """
        If the object is persistent, each request goes to the prefetcher.
        Args:
             key: the dictionary key
        Returns
             item: value found in position key
        """
        log.debug('GET ITEM %s', key)

        if not self._is_persistent:
            return dict.__getitem__(self, key)

        else:
            cres = self._hcache.get_row(self._make_key(key))
            log.debug("GET ITEM %s[%s]", cres, cres.__class__)

            if issubclass(cres.__class__, NoneType):
                return None
            elif self._column_builder is not None:
                return self._column_builder(cres)
            else:
                return cres

    def __setitem__(self, key, val):
        """
           Launches the setitem of the dict found in the block storageobj
           Args:
               key: the position of the value that we want to save
               val: the value that we want to save in that position
           Returns:
        """
        log.debug('SET ITEM %s->%s', key, val)
        if not self._is_persistent:
            dict.__setitem__(self, key, val)
        else:
            self._hcache.put_row(self._make_key(key), self._make_value(val))

    def getID(self):
        """
        Obtains the id of the block
        Returns:
            self.blockid: id of the block
        """
        return self.dict_id

    def iterkeys(self):
        """
        Obtains the iterator for the keys of the block
        Returns:
            iterkeys(self): list of keys
        """
        if self._is_persistent:
            ik = self._hcache.iterkeys(config.prefetch_size)
            return NamedIterator(ik, self._key_builder)
        else:
            return dict.iterkeys(self)

    def iteritems(self):
        """
        Obtains the iterator for the key,val pairs of the block
        Returns:
            BlockItemsIter(self): list of key,val pairs
        """
        if self._is_persistent:
            ik = self._hcache.iteritems(config.prefetch_size)
            return NamedItemsIterator(self._key_builder, self._column_builder, self._k_size, ik)
        else:
            return dict.iteritems(self)

    def itervalues(self):
        """
        Obtains the iterator for the values of the block
        Returns:
            BlockValuesIter(self): list of values
        """
        if self._is_persistent:
            ik = self._hcache.itervalues(config.prefetch_size)
            return NamedIterator(ik, self._column_builder)
        else:
            return dict.itervalues(self)
<|endoftext|>


<commit_before>import rdtest
import struct
import renderdoc as rd

class VK_Discard_Zoo(rdtest.Discard_Zoo):
    demos_test_name = 'VK_Discard_Zoo'
    internal = False

    def __init__(self):
        rdtest.Discard_Zoo.__init__(self)

    def check_capture(self):
        self.check_textures()

        # Test render pass attachments
        draw = self.find_draw("TestStart")

        rpcol: rd.TextureDescription = self.get_texture(
            [res for res in self.controller.GetResources() if "RPCol" in res.name][0].resourceId)
        rpdepth: rd.TextureDescription = self.get_texture(
            [res for res in self.controller.GetResources() if "RPDepth" in res.name][0].resourceId)

        self.check(draw is not None)

        self.controller.SetFrameEvent(draw.next.eventId, True)

        # At the start they should be cleared

        for y in range(0, rpcol.height-1, 17):
            for x in range(0, rpcol.width-1, 17):
                self.check_pixel_value(rpcol.resourceId, x, y, [0.0, 1.0, 0.0, 1.0])
                self.check_pixel_value(rpdepth.resourceId, x, y, [0.4, float(0x40)/float(255), 0.0, 1.0])

        draw = self.find_draw("TestMiddle")

        self.controller.SetFrameEvent(draw.next.eventId, True)

        for y in range(0, rpcol.height-1, 17):
            for x in range(0, rpcol.width-1, 17):

                # if we're in the rect, check for pattern colors
                if 50 <= x < 125 and 50 <= y < 125:
                    c: rd.PixelValue = self.controller.PickPixel(rpcol.resourceId, x, y, rd.Subresource(),
                                                                 rd.CompType.Typeless)
                    d: rd.PixelValue = self.controller.PickPixel(rpdepth.resourceId, x, y, rd.Subresource(),
                                                                 rd.CompType.Typeless)

                    if not rdtest.value_compare(c.floatValue, [0.0] * 4) and not rdtest.value_compare(c.floatValue,
                                                                                [1000.0] * 4):
                        raise rdtest.TestFailureException(
                            'middle color has unexpected value at {},{}: {}'.format(x, y, c.floatValue))

                    if not rdtest.value_compare(d.floatValue[0:2], [0.0] * 2) and not rdtest.value_compare(
                            d.floatValue[0:2], [1.0] * 2):
                        raise rdtest.TestFailureException(
                            'middle depth has unexpected value at {},{}: {}'.format(x, y, d.floatValue))
                else:
                    self.check_pixel_value(rpcol.resourceId, x, y, [0.0, 1.0, 0.0, 1.0])
                    self.check_pixel_value(rpdepth.resourceId, x, y, [0.4, float(0x40)/float(255), 0.0, 1.0])

        middle_col_bytes = self.controller.GetTextureData(rpcol.resourceId, rd.Subresource())
        middle_depth_bytes = self.controller.GetTextureData(rpdepth.resourceId, rd.Subresource())

        draw = self.find_draw("TestEnd")

        self.controller.SetFrameEvent(draw.next.eventId, True)

        for y in range(0, rpcol.height-1, 17):
            for x in range(0, rpcol.width-1, 17):

                # if we're in the rect, check for pattern colors
                if 50 <= x < 125 and 50 <= y < 125:
                    c: rd.PixelValue = self.controller.PickPixel(rpcol.resourceId, x, y, rd.Subresource(),
                                                                 rd.CompType.Typeless)
                    d: rd.PixelValue = self.controller.PickPixel(rpdepth.resourceId, x, y, rd.Subresource(),
                                                                 rd.CompType.Typeless)

                    if not rdtest.value_compare(c.floatValue, [0.0] * 4) and not rdtest.value_compare(c.floatValue,
                                                                                [1000.0] * 4):
                        raise rdtest.TestFailureException(
                            'middle color has unexpected value at {},{}: {}'.format(x, y, c.floatValue))

                    if not rdtest.value_compare(d.floatValue[0:2], [0.0] * 2) and not rdtest.value_compare(
                            d.floatValue[0:2], [1.0] * 2):
                        raise rdtest.TestFailureException(
                            'middle depth has unexpected value at {},{}: {}'.format(x, y, d.floatValue))
                else:
                    self.check_pixel_value(rpcol.resourceId, x, y, [0.0, 1.0, 0.0, 1.0])
                    self.check_pixel_value(rpdepth.resourceId, x, y, [0.4, float(0x40)/float(255), 0.0, 1.0])

        end_col_bytes = self.controller.GetTextureData(rpcol.resourceId, rd.Subresource())
        end_depth_bytes = self.controller.GetTextureData(rpdepth.resourceId, rd.Subresource())

        self.check(middle_col_bytes != end_col_bytes)
        self.check(middle_depth_bytes != end_depth_bytes)<commit_msg>Add success logs when each renderpass segment is verified<commit_after>import rdtest
import struct
import renderdoc as rd

class VK_Discard_Zoo(rdtest.Discard_Zoo):
    demos_test_name = 'VK_Discard_Zoo'
    internal = False

    def __init__(self):
        rdtest.Discard_Zoo.__init__(self)

    def check_capture(self):
        self.check_textures()

        # Test render pass attachments
        draw = self.find_draw("TestStart")

        rpcol: rd.TextureDescription = self.get_texture(
            [res for res in self.controller.GetResources() if "RPCol" in res.name][0].resourceId)
        rpdepth: rd.TextureDescription = self.get_texture(
            [res for res in self.controller.GetResources() if "RPDepth" in res.name][0].resourceId)

        self.check(draw is not None)

        self.controller.SetFrameEvent(draw.next.eventId, True)

        # At the start they should be cleared

        for y in range(0, rpcol.height-1, 17):
            for x in range(0, rpcol.width-1, 17):
                self.check_pixel_value(rpcol.resourceId, x, y, [0.0, 1.0, 0.0, 1.0])
                self.check_pixel_value(rpdepth.resourceId, x, y, [0.4, float(0x40)/float(255), 0.0, 1.0])

        rdtest.log.success("Values are correct before the renderpass")

        draw = self.find_draw("TestMiddle")

        self.controller.SetFrameEvent(draw.next.eventId, True)

        for y in range(0, rpcol.height-1, 17):
            for x in range(0, rpcol.width-1, 17):

                # if we're in the rect, check for pattern colors
                if 50 <= x < 125 and 50 <= y < 125:
                    c: rd.PixelValue = self.controller.PickPixel(rpcol.resourceId, x, y, rd.Subresource(),
                                                                 rd.CompType.Typeless)
                    d: rd.PixelValue = self.controller.PickPixel(rpdepth.resourceId, x, y, rd.Subresource(),
                                                                 rd.CompType.Typeless)

                    if not rdtest.value_compare(c.floatValue, [0.0] * 4) and not rdtest.value_compare(c.floatValue,
                                                                                [1000.0] * 4):
                        raise rdtest.TestFailureException(
                            'middle color has unexpected value at {},{}: {}'.format(x, y, c.floatValue))

                    if not rdtest.value_compare(d.floatValue[0:2], [0.0] * 2) and not rdtest.value_compare(
                            d.floatValue[0:2], [1.0] * 2):
                        raise rdtest.TestFailureException(
                            'middle depth has unexpected value at {},{}: {}'.format(x, y, d.floatValue))
                else:
                    self.check_pixel_value(rpcol.resourceId, x, y, [0.0, 1.0, 0.0, 1.0])
                    self.check_pixel_value(rpdepth.resourceId, x, y, [0.4, float(0x40)/float(255), 0.0, 1.0])

        middle_col_bytes = self.controller.GetTextureData(rpcol.resourceId, rd.Subresource())
        middle_depth_bytes = self.controller.GetTextureData(rpdepth.resourceId, rd.Subresource())

        rdtest.log.success("Values are correct in the middle of the renderpass")

        draw = self.find_draw("TestEnd")

        self.controller.SetFrameEvent(draw.next.eventId, True)

        for y in range(0, rpcol.height-1, 17):
            for x in range(0, rpcol.width-1, 17):

                # if we're in the rect, check for pattern colors
                if 50 <= x < 125 and 50 <= y < 125:
                    c: rd.PixelValue = self.controller.PickPixel(rpcol.resourceId, x, y, rd.Subresource(),
                                                                 rd.CompType.Typeless)
                    d: rd.PixelValue = self.controller.PickPixel(rpdepth.resourceId, x, y, rd.Subresource(),
                                                                 rd.CompType.Typeless)

                    if not rdtest.value_compare(c.floatValue, [0.0] * 4) and not rdtest.value_compare(c.floatValue,
                                                                                [1000.0] * 4):
                        raise rdtest.TestFailureException(
                            'middle color has unexpected value at {},{}: {}'.format(x, y, c.floatValue))

                    if not rdtest.value_compare(d.floatValue[0:2], [0.0] * 2) and not rdtest.value_compare(
                            d.floatValue[0:2], [1.0] * 2):
                        raise rdtest.TestFailureException(
                            'middle depth has unexpected value at {},{}: {}'.format(x, y, d.floatValue))
                else:
                    self.check_pixel_value(rpcol.resourceId, x, y, [0.0, 1.0, 0.0, 1.0])
                    self.check_pixel_value(rpdepth.resourceId, x, y, [0.4, float(0x40)/float(255), 0.0, 1.0])

        rdtest.log.success("Values are correct after the renderpass")

        end_col_bytes = self.controller.GetTextureData(rpcol.resourceId, rd.Subresource())
        end_depth_bytes = self.controller.GetTextureData(rpdepth.resourceId, rd.Subresource())

        self.check(middle_col_bytes != end_col_bytes)
        self.check(middle_depth_bytes != end_depth_bytes)<|endoftext|>