summaryrefslogtreecommitdiffstats
path: root/bitvend/mdb.py
blob: d6d3b4b37bc9998c5baecfe30d43dad23d82fb97 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import time

from bitvend.models import db, Transaction
from bitvend.stats import cashless_purchase_counter, coin_counter, purchase_counter

from mdb.device import CashlessMDBDevice
from mdb.constants import *


class BitvendCashlessMDBDevice(CashlessMDBDevice):
    current_tx_id = None
    app = None

    def init_app(self, app):
        self.app = app

    def begin_session(self, amount, tx_id=None):
        self.current_tx_id = tx_id

        super(BitvendCashlessMDBDevice, self).begin_session(amount)

    def vend_request(self, product, value):
        # FIXME we report success here, because database write takes too much
        # time to respond in 5ms.
        self.send([0x05, 0x00, 0xff])
        self.poll_queue.put([0x05])
        self.current_request.processed = True

        self.logger.info('got vend request: %r', self.current_tx_id)

        if self.current_tx_id:
            with self.app.app_context():
                tx = Transaction.query.get(self.current_tx_id)
                tx.product_id = product
                tx.product_value = value

                if tx.amount is None:
                    tx.amount = -value

                db.session.commit()

            self.current_tx_id = None

            cashless_purchase_counter.inc()

        return True

    last_purchase = 0

    def process_request(self, req):
        if req.command == COIN_EXP and req.validate_checksum() and req.data[0] == COIN_EXP_PAYOUT and not req.processed:
            self.logger.info('Purchase with change detected')
            req.processed = True
            if time.time() - self.last_purchase > 5:
                purchase_counter.inc()
            self.last_purchase = time.time()
        elif req.command == COIN_TYPE and req.validate_checksum() and not req.processed:
            self.logger.info('Purchase without detected')
            req.processed = True
            if time.time() - self.last_purchase > 5:
                purchase_counter.inc()
            self.last_purchase = time.time()
        elif req.command == COIN_POLL and req.validate_checksum() and not req.processed and req.ack:
            self.logger.info('Coin detected')
            req.processed = True
            coin_counter.inc()

        return super(BitvendCashlessMDBDevice, self).process_request(req)