Added a *lot* of documentation
This commit is contained in:
		
							parent
							
								
									7850b322c5
								
							
						
					
					
						commit
						4fbd3c6651
					
				| 
						 | 
					@ -29,7 +29,7 @@ Open for discussion:
 | 
				
			||||||
	  - 15, besser 20:Man sucht auf ja nach etwas und will sich nicht totklicken ~~~TKroenert
 | 
						  - 15, besser 20:Man sucht auf ja nach etwas und will sich nicht totklicken ~~~TKroenert
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Konrad:
 | 
					Konrad:
 | 
				
			||||||
	Abmeldenutton rechts oder rot?
 | 
						Abmeldebutton rechts oder rot?
 | 
				
			||||||
	- die liste der zu einkaufenden items ist doof :(
 | 
						- die liste der zu einkaufenden items ist doof :(
 | 
				
			||||||
	- /store/history/ ist noch kaputt + zeit unformatiert
 | 
						- /store/history/ ist noch kaputt + zeit unformatiert
 | 
				
			||||||
	- /transaction/ sehen die gemachten transactions noch nicht so cool aus
 | 
						- /transaction/ sehen die gemachten transactions noch nicht so cool aus
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,14 +4,15 @@ from piston.utils import rc
 | 
				
			||||||
from main.models import Plugin, PluginPermission
 | 
					from main.models import Plugin, PluginPermission
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def manglePluginPerms(apiFunc):
 | 
					def manglePluginPerms(apiFunc):
 | 
				
			||||||
	""" Changes to a given user when the authenticated user is an plugin
 | 
						""" Changes to a given user when the authenticated user is an plugin.
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
		When the user which called the apifunc is an plugin this function
 | 
						When the user which called the apifunc is a plugin this function
 | 
				
			||||||
	goes through the following steps:
 | 
						goes through the following steps:
 | 
				
			||||||
		- searches the user it should change to
 | 
							- searches the user it should change to
 | 
				
			||||||
		- checks if this user allowed the plugin to "speak for him"
 | 
							- checks if this user allowed the plugin to "speak for him"
 | 
				
			||||||
		- change the request so it looks like the user called himself
 | 
							- change the request so it looks like the user called himself
 | 
				
			||||||
		- add an plugin_user entry containing the previous request user
 | 
							- add an plugin_user entry containing the previous request user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	This decorator is intended to be used with django piston, so on error
 | 
						This decorator is intended to be used with django piston, so on error
 | 
				
			||||||
	it will return the appropriate rc.* values.
 | 
						it will return the appropriate rc.* values.
 | 
				
			||||||
	"""
 | 
						"""
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,12 +1,14 @@
 | 
				
			||||||
from decimal import Decimal, InvalidOperation
 | 
					from decimal import Decimal, InvalidOperation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def getInt(d, key, default):
 | 
					def getInt(d, key, default):
 | 
				
			||||||
 | 
						""" Helper for dict.get to return the default on error. """
 | 
				
			||||||
	try:
 | 
						try:
 | 
				
			||||||
		return int(d.get(key, default))
 | 
							return int(d.get(key, default))
 | 
				
			||||||
	except ValueError:
 | 
						except ValueError:
 | 
				
			||||||
		return default
 | 
							return default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def getDecimal(d, key, default):
 | 
					def getDecimal(d, key, default):
 | 
				
			||||||
 | 
						""" Helper for dict.get to return the default on error. """
 | 
				
			||||||
	try:
 | 
						try:
 | 
				
			||||||
		return Decimal(d.get(key, default))
 | 
							return Decimal(d.get(key, default))
 | 
				
			||||||
	except InvalidOperation:
 | 
						except InvalidOperation:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,9 +4,13 @@ from piston.authentication import HttpBasicAuthentication
 | 
				
			||||||
from api2.authentication import DjangoAuthentication, MultiAuthentication
 | 
					from api2.authentication import DjangoAuthentication, MultiAuthentication
 | 
				
			||||||
from api2.handlers import *
 | 
					from api2.handlers import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# taken from
 | 
					 | 
				
			||||||
# http://www.robertshady.com/content/creating-very-basic-api-using-python-django-and-piston
 | 
					 | 
				
			||||||
class CsrfExemptResource( Resource ):
 | 
					class CsrfExemptResource( Resource ):
 | 
				
			||||||
 | 
						""" Except a :class:`Resource` from djangos CSRF-Framework.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							This idea is taken from
 | 
				
			||||||
 | 
							http://www.robertshady.com/content/creating-very-basic-api-using-python-django-and-piston
 | 
				
			||||||
 | 
						"""
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	def __init__( self, handler, authentication = None ):
 | 
						def __init__( self, handler, authentication = None ):
 | 
				
			||||||
		super( CsrfExemptResource, self ).__init__( handler, authentication )
 | 
							super( CsrfExemptResource, self ).__init__( handler, authentication )
 | 
				
			||||||
		self.csrf_exempt = getattr( self.handler, 'csrf_exempt', True )
 | 
							self.csrf_exempt = getattr( self.handler, 'csrf_exempt', True )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,7 @@ class Buyable(models.Model):
 | 
				
			||||||
		return self.deposit > Decimal(0)
 | 
							return self.deposit > Decimal(0)
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	def createPurchase(self, isDeposit=False):
 | 
						def createPurchase(self, isDeposit=False):
 | 
				
			||||||
 | 
							""" Creates a :class:`Purchase` containing this :class:`Buyable`. """
 | 
				
			||||||
		p = Purchase()
 | 
							p = Purchase()
 | 
				
			||||||
		if isDeposit:
 | 
							if isDeposit:
 | 
				
			||||||
			p.price = self.deposit
 | 
								p.price = self.deposit
 | 
				
			||||||
| 
						 | 
					@ -47,11 +48,7 @@ class Buyable(models.Model):
 | 
				
			||||||
		return item
 | 
							return item
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Order(models.Model):
 | 
					class Order(models.Model):
 | 
				
			||||||
	""" Represents an order by the user.
 | 
						""" Represents an order by the user, consists of several :class:`Purchases <Purchase>`. """
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"""
 | 
					 | 
				
			||||||
	An Order object is referenced by all :class:`Purchases <Purchase>`
 | 
					 | 
				
			||||||
	user = models.ForeignKey(User)
 | 
						user = models.ForeignKey(User)
 | 
				
			||||||
	price = models.DecimalField(max_digits=8, decimal_places=2)
 | 
						price = models.DecimalField(max_digits=8, decimal_places=2)
 | 
				
			||||||
	dateTime = models.DateTimeField()
 | 
						dateTime = models.DateTimeField()
 | 
				
			||||||
| 
						 | 
					@ -93,7 +90,7 @@ class Order(models.Model):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Purchase(models.Model):
 | 
					class Purchase(models.Model):
 | 
				
			||||||
	""" Represents a :class:``"""
 | 
						""" Represents a :class:`Buyable` in a :class:`Order`"""
 | 
				
			||||||
	order = models.ForeignKey(Order)
 | 
						order = models.ForeignKey(Order)
 | 
				
			||||||
	price = models.DecimalField(max_digits=8, decimal_places=2)
 | 
						price = models.DecimalField(max_digits=8, decimal_places=2)
 | 
				
			||||||
	isDeposit = models.BooleanField()
 | 
						isDeposit = models.BooleanField()
 | 
				
			||||||
| 
						 | 
					@ -101,6 +98,7 @@ class Purchase(models.Model):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@staticmethod
 | 
						@staticmethod
 | 
				
			||||||
	def create(order, buyable, isDeposit=False):
 | 
						def create(order, buyable, isDeposit=False):
 | 
				
			||||||
 | 
							""" Create a Purchase from a buyable. Still needs to be saved. """
 | 
				
			||||||
		p = Purchase()
 | 
							p = Purchase()
 | 
				
			||||||
		p.order = order
 | 
							p.order = order
 | 
				
			||||||
		p.isDeposit = isDeposit
 | 
							p.isDeposit = isDeposit
 | 
				
			||||||
| 
						 | 
					@ -116,12 +114,3 @@ class Purchase(models.Model):
 | 
				
			||||||
	def __unicode__(self):
 | 
						def __unicode__(self):
 | 
				
			||||||
		return "%s%s" % (self.buyable.name, (self.isDeposit and " (deposit)" or ""))
 | 
							return "%s%s" % (self.buyable.name, (self.isDeposit and " (deposit)" or ""))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#	def save(self, *args, **kwargs):
 | 
					 | 
				
			||||||
#		profile = self.user.get_profile()
 | 
					 | 
				
			||||||
#		if self.id == None:
 | 
					 | 
				
			||||||
#			# new item, get it!
 | 
					 | 
				
			||||||
#			profile.balance -= self.price
 | 
					 | 
				
			||||||
#			profile.save()
 | 
					 | 
				
			||||||
#		super(Purchase, self).save(*args, **kwargs)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,6 +54,7 @@ def buyItem(request, itemid, buymode=""):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
def boughtItem(request, orderid):
 | 
					def boughtItem(request, orderid):
 | 
				
			||||||
 | 
						""" View which shows what was bought."""
 | 
				
			||||||
	error = None
 | 
						error = None
 | 
				
			||||||
	try:
 | 
						try:
 | 
				
			||||||
		item = Order.objects.get(id=orderid)
 | 
							item = Order.objects.get(id=orderid)
 | 
				
			||||||
| 
						 | 
					@ -66,6 +67,7 @@ def boughtItem(request, orderid):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
def history(request):
 | 
					def history(request):
 | 
				
			||||||
 | 
						""" Show the users previous orders. """
 | 
				
			||||||
	hist = Order.objects.filter(user=request.user.id).order_by("-dateTime")
 | 
						hist = Order.objects.filter(user=request.user.id).order_by("-dateTime")
 | 
				
			||||||
	paginator = Paginator(hist, 10, orphans=3)
 | 
						paginator = Paginator(hist, 10, orphans=3)
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,22 +1,24 @@
 | 
				
			||||||
API
 | 
					API
 | 
				
			||||||
===
 | 
					===
 | 
				
			||||||
 - explain a bit how piston/REST works
 | 
					 | 
				
			||||||
 - how to access the read/write/put/create functions
 | 
					 | 
				
			||||||
 - what this api does and what not
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
K4ever has a REST-like API. This means every URL represents an object which has
 | 
					K4ever has a REST-like API. This means every URL represents an object which has
 | 
				
			||||||
four functions: `read`, `create`, `update` and `delete`. These functions are mapped
 | 
					four functions: ``read``, ``create``, ``update`` and ``delete``. These functions are mapped
 | 
				
			||||||
to the `HTTP`-Methods `GET`, `POST`, `PUT` and `DELETE`. Most of the functionality
 | 
					to the ``HTTP``-Methods ``GET``, ``POST``, ``PUT`` and ``DELETE``. Most of the functionality
 | 
				
			||||||
uses only `GET` and `POST`, so everything is accessible via `wget`.
 | 
					uses only ``GET`` and ``POST``, so everything is accessible via ``wget``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The API enables you to list available items, buy them and transtact money to your
 | 
					The API enables you to list available items, buy them and transtact money to your
 | 
				
			||||||
accout. It also has a *plugin*-concept. Plugins can be allowed by other user
 | 
					accout. To get an idea what functions are available and how they are used scroll down
 | 
				
			||||||
 | 
					to the URLs section. Some URLs take arguments. For a ``GET``-request you can attach
 | 
				
			||||||
 | 
					them normaly, e.g. `/buyable/item/?barcode=4029764001807`. For a ``POST``, ``PUT`` or
 | 
				
			||||||
 | 
					``DELETE`` request the parameters have to be put in the ``HTTP``-requests body. They
 | 
				
			||||||
 | 
					can be provided url, JSON or YAML-encoded - dealers choice.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Authentication can be done either per HTTP Basic Auth or, for AJAX-Requests, per
 | 
				
			||||||
 | 
					cookie (as in "logged in via the webinterface"). Note that most ``HTTP``-libraries
 | 
				
			||||||
 | 
					like pythons urllib2 (or as a tool ``wget``) don't send authenticationdata except
 | 
				
			||||||
 | 
					when being challenged with a ``HTTP 401 - Authentication required``, meaning that
 | 
				
			||||||
 | 
					every API-call requires the library to make two requests. In general this behaviour
 | 
				
			||||||
 | 
					can be turned off.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Authentication can be done either per HTTP Basic Auth or for AJAX-Requests per
 | 
					 | 
				
			||||||
cookie. The 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
k4evers API 
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Plugins
 | 
					Plugins
 | 
				
			||||||
--------------
 | 
					--------------
 | 
				
			||||||
| 
						 | 
					@ -25,7 +27,24 @@ Plugins
 | 
				
			||||||
 - when does a plugin need an user?
 | 
					 - when does a plugin need an user?
 | 
				
			||||||
 - how to change user names
 | 
					 - how to change user names
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					k4evers API also has a *plugin*-concept. :class:`Plugins <main.models.Plugin>`
 | 
				
			||||||
 | 
					can be allowed by users to buy items on their behalf. To do this the user
 | 
				
			||||||
 | 
					has to allow the plugin via the webinterface. A :class:`PluginPermission
 | 
				
			||||||
 | 
					<main.models.PluginPermission>` object will be created to keep track of this.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Each :class:`PluginPermission <main.models.PluginPermission>` object has an
 | 
				
			||||||
 | 
					:attr:`authblob <main.models.PluginPermission.authblob>` in which the plugin
 | 
				
			||||||
 | 
					can save or access arbitrary data on a per-user basis. The plugin has several
 | 
				
			||||||
 | 
					configuration options for the `authblob`. They control read/write access for 
 | 
				
			||||||
 | 
					plugin (via API) or user (via webinterface) to the `authblob` and if the 
 | 
				
			||||||
 | 
					`authblob` has to be unique. The latter one can be useful if the `authblob`
 | 
				
			||||||
 | 
					is needed to be primary key and identify exactly one user
 | 
				
			||||||
 | 
					(see also :ref:`apilink <authblob-authentication>`).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To do something as another user the plugin can, if allowed by the user, add
 | 
				
			||||||
 | 
					the `user`-parameter with the **username** (not the id) to all its requests.
 | 
				
			||||||
 | 
					E.g. to get the account balance of the user *cat* this would look like
 | 
				
			||||||
 | 
					`user/account/?user=cat`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
URLs
 | 
					URLs
 | 
				
			||||||
----
 | 
					----
 | 
				
			||||||
| 
						 | 
					@ -111,6 +130,9 @@ to the handler or the responsible method for more documentation or code.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	:func:`POST <api2.handlers.AuthBlobHandler.create>`
 | 
						:func:`POST <api2.handlers.AuthBlobHandler.create>`
 | 
				
			||||||
   		Set authblob if allowed
 | 
					   		Set authblob if allowed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 .. _authblob-authentication:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 :class:`user/ <api2.handlers.AuthUserHandler>`
 | 
					 :class:`user/ <api2.handlers.AuthUserHandler>`
 | 
				
			||||||
   	:func:`GET <api2.handlers.AuthUserHandler.read>`
 | 
					   	:func:`GET <api2.handlers.AuthUserHandler.read>`
 | 
				
			||||||
   		get user by authblob string - this function works only when plugin
 | 
					   		get user by authblob string - this function works only when plugin
 | 
				
			||||||
| 
						 | 
					@ -132,20 +154,21 @@ Handler
 | 
				
			||||||
.. automodule:: api2.handlers
 | 
					.. automodule:: api2.handlers
 | 
				
			||||||
	:members:
 | 
						:members:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Plugin Models
 | 
				
			||||||
 | 
					-------------
 | 
				
			||||||
 | 
					.. autoclass:: main.models.Plugin
 | 
				
			||||||
 | 
						:members:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. autoclass:: main.models.PluginPermission
 | 
				
			||||||
 | 
						:members:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Decorators
 | 
				
			||||||
 | 
					----------
 | 
				
			||||||
 | 
					.. automodule:: api2.decorators
 | 
				
			||||||
 | 
						:members:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Examples
 | 
					Examples
 | 
				
			||||||
--------
 | 
					--------
 | 
				
			||||||
 - how to use the api
 | 
					 - how to use the api
 | 
				
			||||||
 - examples with... wget.. python-rest?
 | 
					 - examples with... wget.. python-rest?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
As normal user
 | 
					 | 
				
			||||||
^^^^^^^^^^^^^^
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. note:: there will be cat content
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
wget
 | 
					 | 
				
			||||||
""""
 | 
					 | 
				
			||||||
wget part
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
As a plugin
 | 
					 | 
				
			||||||
^^^^^^^^^^^
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +0,0 @@
 | 
				
			||||||
from django_auth_ldap.backend import LDAPBackend
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CustomLDAPBackend(LDAPBackend):
 | 
					 | 
				
			||||||
	def populate_user(username):
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
| 
						 | 
					@ -30,6 +30,7 @@ class CurrencyInput (forms.TextInput):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CurrencyField (forms.RegexField):
 | 
					class CurrencyField (forms.RegexField):
 | 
				
			||||||
 | 
						""" Represents a currency field for django forms... or something. """
 | 
				
			||||||
	widget = CurrencyInput
 | 
						widget = CurrencyInput
 | 
				
			||||||
	currencyRe = re.compile(r'^[0-9]{1,5}([,\.][0-9][0-9]?)?$')
 | 
						currencyRe = re.compile(r'^[0-9]{1,5}([,\.][0-9][0-9]?)?$')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@ from django.contrib.auth.models import User
 | 
				
			||||||
from decimal import Decimal
 | 
					from decimal import Decimal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class UserProfile(models.Model):
 | 
					class UserProfile(models.Model):
 | 
				
			||||||
 | 
						""" Contains data for a user, especially the account balance. """
 | 
				
			||||||
	user = models.ForeignKey(User, unique=True)
 | 
						user = models.ForeignKey(User, unique=True)
 | 
				
			||||||
	balance = models.DecimalField(max_digits=9, decimal_places=2, default=Decimal(0))
 | 
						balance = models.DecimalField(max_digits=9, decimal_places=2, default=Decimal(0))
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
| 
						 | 
					@ -11,6 +12,7 @@ class UserProfile(models.Model):
 | 
				
			||||||
		return "%s (Kontostand: %s)" % (self.user ,self.balance)
 | 
							return "%s (Kontostand: %s)" % (self.user ,self.balance)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def createUserProfile(sender, instance, created, **kwargs):
 | 
					def createUserProfile(sender, instance, created, **kwargs):
 | 
				
			||||||
 | 
						""" Hook to create a new :class:`UserProfile` if the user is created. """
 | 
				
			||||||
	if created:
 | 
						if created:
 | 
				
			||||||
		profile = UserProfile()
 | 
							profile = UserProfile()
 | 
				
			||||||
		profile.user = instance
 | 
							profile.user = instance
 | 
				
			||||||
| 
						 | 
					@ -19,6 +21,19 @@ def createUserProfile(sender, instance, created, **kwargs):
 | 
				
			||||||
post_save.connect(createUserProfile, sender=User)
 | 
					post_save.connect(createUserProfile, sender=User)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Plugin(models.Model):
 | 
					class Plugin(models.Model):
 | 
				
			||||||
 | 
						""" This Model contains a plugin and its configuration.
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						A Plugin consists of its own information (name, author, version
 | 
				
			||||||
 | 
						and descrption) which is displayed for the user on the plugin
 | 
				
			||||||
 | 
						selection page, a configuration what a plugin is allowed to do
 | 
				
			||||||
 | 
						and what not and an own user for authentication against the
 | 
				
			||||||
 | 
						API.
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						:attr:`uniqueAuthblob` is used if the :class:`Plugin` has to uniquely
 | 
				
			||||||
 | 
						identify an user by his/her :attr:`authblob <PluginPermission.authblob>`.
 | 
				
			||||||
 | 
						The other attributes are used for plugin/user read/write access to the
 | 
				
			||||||
 | 
						authblob.
 | 
				
			||||||
 | 
						"""
 | 
				
			||||||
	user = models.ForeignKey(User, unique=True)
 | 
						user = models.ForeignKey(User, unique=True)
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	# plugin info
 | 
						# plugin info
 | 
				
			||||||
| 
						 | 
					@ -39,8 +54,15 @@ class Plugin(models.Model):
 | 
				
			||||||
		return self.name
 | 
							return self.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PluginPermission(models.Model):
 | 
					class PluginPermission(models.Model):
 | 
				
			||||||
 | 
						""" States that a user allows access to his/her account to a :class:`Plugin`.
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
							The :attr:`authblob` can be used by the Plugin to store
 | 
				
			||||||
 | 
							authentication data, e.g. a barcode or hashed password.
 | 
				
			||||||
 | 
						"""
 | 
				
			||||||
	user = models.ForeignKey(User)
 | 
						user = models.ForeignKey(User)
 | 
				
			||||||
	plugin = models.ForeignKey('Plugin')
 | 
						plugin = models.ForeignKey('Plugin')
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						#: authblob which holds arbitrary authentication data.
 | 
				
			||||||
	authblob = models.TextField(default='')
 | 
						authblob = models.TextField(default='')
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	def __unicode__(self):
 | 
						def __unicode__(self):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,10 +19,12 @@ def startpage(request):
 | 
				
			||||||
	return render_to_response("main/startpage.html", {'allMost' : allMost,'usersMost': usersMost, 'usersLast' : usersLast[:12]}, RequestContext(request))
 | 
						return render_to_response("main/startpage.html", {'allMost' : allMost,'usersMost': usersMost, 'usersLast' : usersLast[:12]}, RequestContext(request))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def register(request):
 | 
					def register(request):
 | 
				
			||||||
 | 
						""" The "no registration available" page... """
 | 
				
			||||||
	return render_to_response("registration/register.html", RequestContext(request))
 | 
						return render_to_response("registration/register.html", RequestContext(request))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def getPluginDict(request):
 | 
					def getPluginDict(request):
 | 
				
			||||||
 | 
						""" Generate a dict containing the users plugin information. """
 | 
				
			||||||
	plugins = Plugin.objects.all()
 | 
						plugins = Plugin.objects.all()
 | 
				
			||||||
	allowed = Plugin.objects.filter(pluginpermission__user=request.user)
 | 
						allowed = Plugin.objects.filter(pluginpermission__user=request.user)
 | 
				
			||||||
	unallowed = Plugin.objects.exclude(pluginpermission__user=request.user)
 | 
						unallowed = Plugin.objects.exclude(pluginpermission__user=request.user)
 | 
				
			||||||
| 
						 | 
					@ -32,10 +34,12 @@ def getPluginDict(request):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
def settings(request):
 | 
					def settings(request):
 | 
				
			||||||
 | 
						""" Render settings page. """
 | 
				
			||||||
	return render_to_response("settings/settings.html", getPluginDict(request), RequestContext(request))
 | 
						return render_to_response("settings/settings.html", getPluginDict(request), RequestContext(request))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
def pluginPermission(request, method, pluginId):
 | 
					def pluginPermission(request, method, pluginId):
 | 
				
			||||||
 | 
						""" View to edit the users :class:`Plugin` permissions. """
 | 
				
			||||||
	plugin = None
 | 
						plugin = None
 | 
				
			||||||
	try:
 | 
						try:
 | 
				
			||||||
		plugin = Plugin.objects.get(id=pluginId)
 | 
							plugin = Plugin.objects.get(id=pluginId)
 | 
				
			||||||
| 
						 | 
					@ -65,6 +69,7 @@ def pluginPermission(request, method, pluginId):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
def pluginAuthblob(request, pluginId):
 | 
					def pluginAuthblob(request, pluginId):
 | 
				
			||||||
 | 
						""" View to edit the users :attr:`authblob <PluginPermission.authblob>`. """
 | 
				
			||||||
	if request.method != "POST":
 | 
						if request.method != "POST":
 | 
				
			||||||
		return HttpResponseRedirect("/user/settings/")
 | 
							return HttpResponseRedirect("/user/settings/")
 | 
				
			||||||
	plugin = None
 | 
						plugin = None
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,7 @@ from models import Transaction
 | 
				
			||||||
from main.fields import CurrencyField
 | 
					from main.fields import CurrencyField
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TransactionForm(forms.ModelForm):
 | 
					class TransactionForm(forms.ModelForm):
 | 
				
			||||||
 | 
						""" ModelForm for :class:`Transactions <Transaction>` with a currency field """
 | 
				
			||||||
	amount = CurrencyField(label='Betrag')
 | 
						amount = CurrencyField(label='Betrag')
 | 
				
			||||||
	class Meta:
 | 
						class Meta:
 | 
				
			||||||
		model = Transaction
 | 
							model = Transaction
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,9 @@ from django.db import models
 | 
				
			||||||
from django.contrib.auth.models import User
 | 
					from django.contrib.auth.models import User
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TransactionType(models.Model):
 | 
					class TransactionType(models.Model):
 | 
				
			||||||
 | 
						""" Type for a :class:`Transaction`. States how the money has
 | 
				
			||||||
 | 
						    been added to the account and if somebody needs to check
 | 
				
			||||||
 | 
							if it was payed. """
 | 
				
			||||||
	name = models.CharField(max_length=100)
 | 
						name = models.CharField(max_length=100)
 | 
				
			||||||
	needsCheck = models.BooleanField(default=True)
 | 
						needsCheck = models.BooleanField(default=True)
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
| 
						 | 
					@ -9,6 +12,7 @@ class TransactionType(models.Model):
 | 
				
			||||||
		return unicode(self.name)
 | 
							return unicode(self.name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Transaction(models.Model):
 | 
					class Transaction(models.Model):
 | 
				
			||||||
 | 
						"""Represents a money transaction into the users account. """
 | 
				
			||||||
	user = models.ForeignKey(User)
 | 
						user = models.ForeignKey(User)
 | 
				
			||||||
	transactionType = models.ForeignKey(TransactionType, verbose_name='Typ')
 | 
						transactionType = models.ForeignKey(TransactionType, verbose_name='Typ')
 | 
				
			||||||
	dateTime = models.DateTimeField()
 | 
						dateTime = models.DateTimeField()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,7 @@ import datetime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
def overview(request):
 | 
					def overview(request):
 | 
				
			||||||
 | 
						""" Creates an overview over the users trasnactions, also handles adding money. """
 | 
				
			||||||
	history = Transaction.objects.filter(user=request.user).order_by("-dateTime")
 | 
						history = Transaction.objects.filter(user=request.user).order_by("-dateTime")
 | 
				
			||||||
	transacted = False
 | 
						transacted = False
 | 
				
			||||||
	error = False
 | 
						error = False
 | 
				
			||||||
| 
						 | 
					@ -26,14 +27,3 @@ def overview(request):
 | 
				
			||||||
		form = TransactionForm()
 | 
							form = TransactionForm()
 | 
				
			||||||
	return render_to_response("transaction/overview.html", {'history': history, 'form': form, 'transacted': transacted, 'error': error}, RequestContext(request))
 | 
						return render_to_response("transaction/overview.html", {'history': history, 'form': form, 'transacted': transacted, 'error': error}, RequestContext(request))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@login_required
 | 
					 | 
				
			||||||
def transact(request):
 | 
					 | 
				
			||||||
	if request.method == 'POST':
 | 
					 | 
				
			||||||
		return render_to_response("transaction/transfered.html", RequestContext(request))
 | 
					 | 
				
			||||||
	else:
 | 
					 | 
				
			||||||
		return HttpResponseRedirect("/transaction/")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#@kassenwart_required
 | 
					 | 
				
			||||||
#def checkTransfers(request):
 | 
					 | 
				
			||||||
#	transfers = Transaction.objects.filter(checked=False).order_by("dateTime")
 | 
					 | 
				
			||||||
#	return render_to_response("transaction/uncheckedTransfers.html", {'transfers' : tranfers}, RequestContext(request))
 | 
					 | 
				
			||||||
		Loading…
	
		Reference in New Issue