From 04f9741de7dafe92a9d576ddf0a904e1d551c07a Mon Sep 17 00:00:00 2001 From: Sebastian Pipping Date: Mon, 24 Oct 2011 19:08:09 +0200 Subject: [PATCH] client-barcode: Implement and integrate bulkbuy --- client-barcode/freitagskasse.py | 25 ++++++++++- client-barcode/freitagslib/commands.py | 3 ++ client-barcode/freitagslib/network.py | 61 +++++++++++++++++++++++--- 3 files changed, 81 insertions(+), 8 deletions(-) diff --git a/client-barcode/freitagskasse.py b/client-barcode/freitagskasse.py index d7cda28..c4f34fb 100644 --- a/client-barcode/freitagskasse.py +++ b/client-barcode/freitagskasse.py @@ -282,7 +282,30 @@ class Status: others.append((compressed_deposit, balance_before)) self.transfers = others - # Process command queue + # Compress BuyCommands, use a single bulkbuy + dummy, initial_balance = self.transfers[0] + balance_before = initial_balance + + buy_commands = list() + non_buy_commands = list() + total_buy_diff = 0 + + for command, dummy in self.transfers: + if isinstance(command, BuyCommand): + buy_commands.append(command) + else: + balance_before += command.difference() + non_buy_commands.append((command, balance_before)) + + try: + net.bulk_buy(buy_commands, self.login_name) + except urllib2.HTTPError as e: + print_display('\x0cFEHLER: Server Error%20s' % str(e)[:20]) + error_page('FEHLER bei Kommunikation mit Server "%s"' % str(e)) + else: + self.transfers = non_buy_commands + + # Process remaining command queue for (command, balance_backup) in list(self.transfers): try: command.run(self.login_name) diff --git a/client-barcode/freitagslib/commands.py b/client-barcode/freitagslib/commands.py index 69a27ab..eaf1d42 100644 --- a/client-barcode/freitagslib/commands.py +++ b/client-barcode/freitagslib/commands.py @@ -58,6 +58,9 @@ class BuyCommand(object): def item_name(self): return self._item.name + def item_id(self): + return self._item.id + def commodity_label(self): if self._deposit or self.deposit_value() <= 0: return self._item.name diff --git a/client-barcode/freitagslib/network.py b/client-barcode/freitagslib/network.py index 4e32ce5..d196f19 100644 --- a/client-barcode/freitagslib/network.py +++ b/client-barcode/freitagslib/network.py @@ -11,6 +11,7 @@ import simplejson as json from decimal import Decimal import os import base64 +import copy if __name__ == '__main__': import sys @@ -31,19 +32,36 @@ _headers = {'Authorization':'Basic %s' % _auth} ITEM_ONLY, DEPOSIT_ONLY, ITEM_AND_DEPOSIT = range(3) -def _request(api_rel_url, para_map, method): +if bool(os.environ.get('BARCODE_PLUGIN_DEBUG', False)): + _h = urllib2.HTTPHandler(debuglevel=1) + _opener = urllib2.build_opener(_h) + _urlopen = _opener.open +else: + _urlopen = urllib2.urlopen + + +def _request(api_rel_url, data, method, headers=None): url = _BASE_URL + api_rel_url - data = urllib.urlencode(para_map) + + if isinstance(data, dict): + data = urllib.urlencode(data) + + # Add default headers + if headers is None: + final_headers = _headers + else: + final_headers = copy.copy(_headers) + final_headers.update(headers) if method == 'GET': url = '%s?%s' % (url, data) - req = urllib2.Request(url, headers=_headers) + req = urllib2.Request(url, headers=final_headers) elif method == 'POST': - req = urllib2.Request(url, data=data, headers=_headers) + req = urllib2.Request(url, data=data, headers=final_headers) else: raise ValueError('Unsupported method "%s"' % method) - response = urllib2.urlopen(req) + response = _urlopen(req) return response.read() @@ -63,6 +81,26 @@ def buy_item(item_id, what_about_it, user_name): raise ValueError('Server says "%s"' % content) +def bulk_buy(buycommands, user_name): + item_ids = tuple(e.item_id() for e in buycommands if e.includes_commodity()) + deposit_ids = tuple(e.item_id() for e in buycommands if e.includes_deposit()) + + request_dict = { + 'user':user_name, + 'items':item_ids, + 'deposits':deposit_ids + } + data = json.dumps(request_dict, sort_keys=True, indent=4 * ' ') + + headers = { + 'Content-Type':'application/json', + 'Content-Length':len(data) + } + content = _request('buyable/item/bulkbuy/', data, 'POST', headers=headers) + if content != 'Created': + raise ValueError('Server says "%s"' % content) + + def get_item(barcode): content = _request('buyable/item/', {'barcode':barcode}, method='GET') @@ -99,5 +137,14 @@ if __name__ == '__main__': deposit(Decimal('0.01'), DEPOSIT_CASH, user_name) deposit(Decimal('0.01'), DEPOSIT_BANK, user_name) - item = get_item(1) - print('Item "%s" is %f Euro each' % (item.name, item.price)) + def show(item): + print('Item "%s" is %f Euro each' % (item.name, item.price)) + + item5 = get_item(5) + item6 = get_item(6) + for item in (item5, item6): + show(item) + + from freitagslib.commands import BuyCommand + buycommands = (BuyCommand(e) for e in (item5, item6)) + bulk_buy(buycommands, user_name)