# Path: opennode/knot/model/compute.py
# class IVirtualCompute(Interface):
#     """A virtual compute."""
#     template = Path(title=u"Template", base_path='../templates/by-name/', relative_to=Path.PARENT)
#     # 0 <= cpu_limit <= 1
#     cpu_limit = schema.Float(title=u"CPU Limit", description=u"CPU usage limit", required=False)
#     ctid = schema.Int(title=u'OpenVZ CTID', description=u'OpenVZ CTID (applies only to OpenVZ VMs)',
#                       required=False, default=101)
# 
#     license_activated = schema.Bool(title=u'License activated', required=False, default=True,
#                                     readonly=True)
# 
#     notify_admin = schema.Bool(title=u'Notify admin on deploy', required=False, default=False,
#                                readonly=True)
# 
# Path: opennode/knot/model/user.py
# class IUserStatisticsLogger(Interface):
# 
#     def log(self, data):
#         """ Log statistics collected using IUserStatisticsProvider """


from datetime import datetime, timedelta
from grokcore.component import implements, name, GlobalUtility
from twisted.internet import defer
from twisted.enterprise import adbapi
from zope.interface import Interface
from zope.component import getUtility
from opennode.knot.model.compute import IVirtualCompute
from opennode.knot.model.user import IUserStatisticsLogger
from opennode.knot.model.virtualizationcontainer import IVirtualizationContainer
from opennode.oms.config import get_config
from opennode.oms.model.model.hooks import IPreValidateHook
from opennode.oms.model.traversal import traverse1
from opennode.oms.zodb import db
import logging
import sys

            log.debug('writing stats: %(user)s numcores: %(num_cores_total)s disk: %(diskspace_total)s '
                      'memory: %(memory_total)s vmcount: %(vm_count)s credit: %(credit)s', logdata)

            yield self._db.runOperation(self.db_operation,
                                        (user, stats_data['timestamp'],
                                         stats_data['num_cores_total'],
                                         # OMS_USAGE db assumes GBs for
                                         # memory while as OMS internally calculates in MBs
                                         stats_data['diskspace_total'],
                                         stats_data['memory_total'] / 1024.0,
                                         stats_data['vm_count'],
                                         stats_data['credit']))

            log.debug('writing stats for %(user)s is done!', logdata)
        except Exception:
            log.error('DB error', exc_info=sys.exc_info())


class UserCreditChecker(GlobalUtility):
    implements(IPreValidateHook)
    name('user-credit-check')

    @db.ro_transact
    def _get_profile_and_need_update(self, principal):
        credit_check_cooldown = get_config().getstring('auth', 'billing_timeout', 60)
        try:
            profile = traverse1('/home/%s' % principal.id)
            timeout = (datetime.strptime(profile.credit_timestamp, '%Y-%m-%dT%H:%M:%S.%f') +
                       timedelta(seconds=credit_check_cooldown))

# Path: opennode/knot/model/compute.py
# class IVirtualCompute(Interface):
#     """A virtual compute."""
#     template = Path(title=u"Template", base_path='../templates/by-name/', relative_to=Path.PARENT)
#     # 0 <= cpu_limit <= 1
#     cpu_limit = schema.Float(title=u"CPU Limit", description=u"CPU usage limit", required=False)
#     ctid = schema.Int(title=u'OpenVZ CTID', description=u'OpenVZ CTID (applies only to OpenVZ VMs)',
#                       required=False, default=101)
# 
#     license_activated = schema.Bool(title=u'License activated', required=False, default=True,
#                                     readonly=True)
# 
#     notify_admin = schema.Bool(title=u'Notify admin on deploy', required=False, default=False,
#                                readonly=True)
# 
# Path: opennode/knot/model/user.py
# class IUserStatisticsLogger(Interface):
# 
#     def log(self, data):
#         """ Log statistics collected using IUserStatisticsProvider """


# Path: opennode/knot/backend/billing.py
from datetime import datetime, timedelta
from grokcore.component import implements, name, GlobalUtility
from twisted.internet import defer
from twisted.enterprise import adbapi
from zope.interface import Interface
from zope.component import getUtility
from opennode.knot.model.compute import IVirtualCompute
from opennode.knot.model.user import IUserStatisticsLogger
from opennode.knot.model.virtualizationcontainer import IVirtualizationContainer
from opennode.oms.config import get_config
from opennode.oms.model.model.hooks import IPreValidateHook
from opennode.oms.model.traversal import traverse1
from opennode.oms.zodb import db
import logging
import sys


            log.debug('writing stats: %(user)s numcores: %(num_cores_total)s disk: %(diskspace_total)s '
                      'memory: %(memory_total)s vmcount: %(vm_count)s credit: %(credit)s', logdata)

            yield self._db.runOperation(self.db_operation,
                                        (user, stats_data['timestamp'],
                                         stats_data['num_cores_total'],
                                         # OMS_USAGE db assumes GBs for
                                         # memory while as OMS internally calculates in MBs
                                         stats_data['diskspace_total'],
                                         stats_data['memory_total'] / 1024.0,
                                         stats_data['vm_count'],
                                         stats_data['credit']))

            log.debug('writing stats for %(user)s is done!', logdata)
        except Exception:
            log.error('DB error', exc_info=sys.exc_info())


class UserCreditChecker(GlobalUtility):
    implements(IPreValidateHook)
    name('user-credit-check')

    @db.ro_transact
    def _get_profile_and_need_update(self, principal):
        credit_check_cooldown = get_config().getstring('auth', 'billing_timeout', 60)
        try:
            profile = traverse1('/home/%s' % principal.id)
            timeout = (datetime.strptime(profile.credit_timestamp, '%Y-%m-%dT%H:%M:%S.%f') +
                       timedelta(seconds=credit_check_cooldown))

            log.debug('Next update for "%s": %s', principal.id, timeout)