from piston.handler import BaseHandler from piston.utils import rc from k4ever.buyable.models import * from k4ever.transaction.models import * from django.contrib.auth.decorators import user_passes_test from django.contrib.auth.models import Group from django.core.exceptions import MultipleObjectsReturned from decorators import * from decimal import Decimal, InvalidOperation from helper import * import datetime class BuyableItemHandler(BaseHandler): """Handler responsible for getting and buying items.""" allowed_methods = ('GET', 'POST') #fields = ('id', 'description') model = Buyable exclude = ('_*',) def read(self, request, itemId=None): """Get one or multiple items. - type: Only get items belonging to this type - barcode: Return only item(s) with this barcode Note that neither type nor barcode is used if an item id is specified. """ barcode = request.GET.get('barcode', None) if itemId == None: obj = Buyable.objects.all() if barcode and barcode != '': # try to get specific object or return 404 try: return Buyable.objects.get(barcode=barcode) except MultipleObjectsReturned: ret = rc.DUPLICATE_ENTRY ret.write("\nWe found more than one entry with this barcode. Bad.\n") return ret except Buyable.DoesNotExist: return rc.NOT_FOUND else: if request.GET.has_key('type'): obj = Buyable.objects.filter(buyableType__name=request.GET['type']) return obj try: return Buyable.objects.get(id=itemId) except Buyable.DoesNotExist: error = rc.NOT_FOUND error.write("This buyable does not exist in our database") return error @manglePluginPerms def create(self, request, itemId=None): """Buy a :class:`Buyable ` item. - deposit Set to > 0 if you want to buy the item with deposit (default 0) - amount amount of items to buy (default 1) """ if not request.content_type: request.data = request.POST if not itemId: return rc.BAD_REQUEST item = None try: item = Buyable.objects.get(id=itemId) except Buyable.DoesNotExist: return rc.NOT_FOUND # parse post data deposit = getInt(request.data, 'deposit', 0) amount = getInt(request.data, 'amount', 1) if amount < 1: return rc.BAD_REQUEST if item.hasDeposit() and deposit > 0: return rc.BAD_REQUEST # this is just the user being plain stupid order = Order() order.create(request.user) order.save() for i in range(amount): p = Purchase.create(order, item, isDeposit=False) p.save() if deposit > 0: p = Purchase.create(order, item, isDeposit=True) p.save() order.updatePrice(commit=True) order.save() return rc.CREATED class BuyableTypeHandler(BaseHandler): """Handler for listing all :class:`BuyableType `. This class only supports read requests which won't accept any arguments. It will give you a list of buyable-types. Nothing more, nothing less. """ allowed_methods = ('GET',) model = BuyableType class HistoryHandler(BaseHandler): """Handler providing access to the users history """ allowed_methods = ('GET',) fields = ('id', 'price', 'dateTime', ('purchase_set', (('buyable', ('id', )), 'price', 'name'))) @manglePluginPerms def read(self, request): """Get the users history - num: Number of entries to return """ num = getInt(request.GET, 'num', 0) qset = Order.objects.filter(user=request.user) if num > 0: return qset[:num] return qset class TransactionTransactHandler(BaseHandler): """Handler for transaction. This hanlder takes care of adding money to accounts and returning previous moneytransfers """ allowed_methods = ('GET', 'POST') model = Transaction fields = ('amount', 'dateTime', 'checked', ('transactionType', ('id', 'name'))) @manglePluginPerms def read(self, request): """Return the users last transactions - num: Number of entries to return """ num = getInt(request.GET, 'num', 0) if num < 0: return rc.BAD_REQUEST userTrans = Transaction.objects.filter(user=request.user) if num > 0: return userTrans[:num] return userTrans @manglePluginPerms def create(self, request): """Transact money to an account - amount: [req] Amount to add to the users account - type: [req]Type of transaction (id) """ amount = getDecimal(request.POST, 'amount', Decimal(0)) tTypeId = getInt(request.POST, 'type', -1) if amount <= 0: ret = rc.BAD_REQUEST rc.write("\nA negative amount is not supported right now (there has not been put enough thought into the 'lending money' process\n") return ret tType = None try: tType = TransactionType.objects.get(id=tTypeId) except TransactionType.DoesNotExist: ret = rc.BAD_REQUEST ret.write("\nYour TransactionType could not be found\n") return ret trans = Transaction() trans.user = request.user trans.transactionType = tType trans.dateTime = datetime.datetime.now() trans.amount = amount trans.save() return rc.ALL_OK class TransactionTypeHandler(BaseHandler): """Handler for :class:`Transaction Types ` Supplies a list of Transaction Types """ allowed_methods = ('GET',) model = TransactionType class AccountBalanceHandler(BaseHandler): """Handler for the users account balance""" allowed_methods = ('GET',) @manglePluginPerms def read(self, request): """Returns the users current account balance""" balance = request.user.get_profile().balance return {'balance': balance} class AuthBlobHandler(BaseHandler): """Handler to read and write an users authblob Currently these functions are only available for a plugin user. Other users will get a rc.FORBIDDEN. Keep in mind that, to use these functions a plugin needs the permissions to do this in its configuration. """ allowed_methods = ('GET', 'POST') @requirePlugin @manglePluginPerms def read(self, request): """Read the users authblob To use this function the plugin needs :attr:`main.models.Plugin.pluginCanReadAuthblob` to be true. """ if not request.plugin.pluginCanReadAuthblob: ret = rc.FORBIDDEN ret.write("\nThis plugin is not allowed to read the users authblob\n") return ret return request.pluginperms.authblob @requirePlugin @manglePluginPerms def create(self, request): """Write the users authblob. To use this function the plugin needs :attr:`main.models.Plugin.pluginCanWriteAuthblob` to be true. .. Note:: In fact this method *should* be an update method, but for compability reasons (wget usage) it was decided to make this accessible as a create (POST) hook. """ if not request.plugin.pluginCanWriteAuthblob: ret = rc.FORBIDDEN ret.write("\nThis plugin is not allowed to write the users authblob\n") return ret if not request.data.has_key('authblob'): ret = rc.BAD_REQUEST ret.write("\nTo change the users auth blob you actually need to provide one\n") request.pluginperms.authblob = request.data['authblob'] request.pluginperms.authblob.save() return rc.ALL_OK class AuthUserHandler(BaseHandler): """ Handler for mapping an authblob to a user This handler is only available to plugins and only if :attr:`unique authblob ` is set for this plugin. Then it will provide a mapping from an authblob to a specifig user. """ allowed_methods = ('GET') fields = ('id', 'username') @requirePlugin def read(self, request): """Returns an user if one can be found, else rc.GONE - authblob: [required] Authblob to search """ if not request.plugin.uniqueAuthblob: ret = rc.BAD_REQUEST ret.write("\nThis plugin does not support unique auth blobs, therefore we can't identify an user uniquely by its authblob\n") return ret if not request.GET.has_key('authblob'): return rc.BAD_REQUEST try: perm = PluginPermission.objects.get(plugin=request.plugin, authblob=request.GET['authblob']) return perm.user except PluginPermission.DoesNotExist: return rc.NOT_FOUND class ConfigHandler(BaseHandler): """ Handler for API configuration values This handler provides some API related configuration values""" allowed_methods = ('GET',) def read(self, request): """Get API configuration values Currently returns the API version and mediaurl (where to find images etc.) """ return { 'version': '0.1', 'mediaurl': 'http://devcat.someserver.de:13805/media', }