You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
k4ever/k4ever/api2/handlers.py

293 lines
8.3 KiB

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 <buyable.models.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 <buyable.models.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 <transaction.models.TransactionType>`
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 <main.models.Plugin.uniqueAuthblob>`
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',
}