Implement a market

This commit is contained in:
Trever Fischer
2012-11-17 16:09:29 -05:00
parent 57b21f9316
commit 563ab161f9
19 changed files with 664 additions and 0 deletions

View File

@@ -64,6 +64,11 @@ class PlayerMessageEvent(Event):
super(PlayerMessageEvent, self).__init__(type='player-message',
data={'message': message, 'player': user})
class MarketOrderEvent(Event):
def __init__(self, orderID):
super(MarketOrderEvent, self).__init__(type='market-order',
data={'orderID': orderID})
def server_queue(server, users=[]):
queueName = 'caminus-broadcast-%s'%server.id
queue = beanstalkc.Connection(host=settings.CAMINUS_BEANSTALKD_HOST,
@@ -110,6 +115,19 @@ def web_queue(id):
queue.watch(queueName)
return queue
def market_queue():
queueName = 'caminus-market'
queue = beanstalkc.Connection(host=settings.CAMINUS_BEANSTALKD_HOST,
port = settings.CAMINUS_BEANSTALKD_PORT)
queue.use(queueName)
queue.watch(queueName)
return queue
def queue_market_event(event):
queue = market_queue()
json = dumps({'stamp': time.time(), 'event': event}, cls=EventEncoder)
queue.put(json)
def send_web_event(event):
latest = cache.get('minecraft-web-events')
if latest is None:

0
market/__init__.py Normal file
View File

5
market/admin.py Normal file
View File

@@ -0,0 +1,5 @@
import models
from django.contrib import admin
admin.site.register(models.MarketOrder)
admin.site.register(models.Transaction)

View File

View File

View File

@@ -0,0 +1,37 @@
from django.core.management.base import NoArgsCommand
from market.models import MarketOrder
import json
from api.events import market_queue
from datetime import datetime
class Command(NoArgsCommand):
help = 'Daemon to process market orders'
def handle_noargs(self, **options):
print "Processing currently open orders"
for order in MarketOrder.objects.filter(close_stamp__isnull=True):
order.process()
queue = market_queue()
while True:
job = queue.reserve()
jobInfo = json.loads(job.body)
if jobInfo['event']['type'] == "market-order":
try:
order = MarketOrder.objects.get(id=jobInfo['event']['payload']['orderID'])
except MarketOrder.DoesNotExist:
# The orders might not be saved yet due to transactions
job.release()
continue
if order.close_stamp:
print "Got event for a closed order", order.id
job.delete()
continue
if order.quantity == 0:
print "Saving bugged order", order.id
order.close_stamp = datetime.now()
order.save()
job.delete()
continue
order.process()
job.delete()

View File

@@ -0,0 +1,88 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'MarketOrder'
db.create_table('market_marketorder', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('item', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['minecraft.Item'])),
('creator', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
('unit_price', self.gf('django.db.models.fields.FloatField')()),
('open_stamp', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
('close_stamp', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
('quantity', self.gf('django.db.models.fields.IntegerField')()),
('type', self.gf('django.db.models.fields.IntegerField')(default=-1)),
))
db.send_create_signal('market', ['MarketOrder'])
def backwards(self, orm):
# Deleting model 'MarketOrder'
db.delete_table('market_marketorder')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'market.marketorder': {
'Meta': {'ordering': "['-open_stamp', 'unit_price']", 'object_name': 'MarketOrder'},
'close_stamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'item': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['minecraft.Item']"}),
'open_stamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'quantity': ('django.db.models.fields.IntegerField', [], {}),
'type': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
'unit_price': ('django.db.models.fields.FloatField', [], {})
},
'minecraft.item': {
'Meta': {'object_name': 'Item'},
'damage': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'data': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'material': ('django.db.models.fields.IntegerField', [], {'default': '0'})
}
}
complete_apps = ['market']

View File

@@ -0,0 +1,79 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'MarketOrder.initial_quantity'
db.add_column('market_marketorder', 'initial_quantity', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
def backwards(self, orm):
# Deleting field 'MarketOrder.initial_quantity'
db.delete_column('market_marketorder', 'initial_quantity')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'market.marketorder': {
'Meta': {'ordering': "['-open_stamp', 'unit_price']", 'object_name': 'MarketOrder'},
'close_stamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'initial_quantity': ('django.db.models.fields.IntegerField', [], {}),
'item': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['minecraft.Item']"}),
'open_stamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'quantity': ('django.db.models.fields.IntegerField', [], {}),
'type': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
'unit_price': ('django.db.models.fields.FloatField', [], {})
},
'minecraft.item': {
'Meta': {'object_name': 'Item'},
'damage': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'data': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'material': ('django.db.models.fields.IntegerField', [], {'default': '0'})
}
}
complete_apps = ['market']

View File

@@ -0,0 +1,94 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'Transaction'
db.create_table('market_transaction', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('buy_order', self.gf('django.db.models.fields.related.ForeignKey')(related_name='buy_transactions', to=orm['market.MarketOrder'])),
('sell_order', self.gf('django.db.models.fields.related.ForeignKey')(related_name='sell_transactions', to=orm['market.MarketOrder'])),
('quantity', self.gf('django.db.models.fields.IntegerField')()),
('stamp', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
))
db.send_create_signal('market', ['Transaction'])
def backwards(self, orm):
# Deleting model 'Transaction'
db.delete_table('market_transaction')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'market.marketorder': {
'Meta': {'ordering': "['-open_stamp', 'unit_price']", 'object_name': 'MarketOrder'},
'close_stamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'initial_quantity': ('django.db.models.fields.IntegerField', [], {}),
'item': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['minecraft.Item']"}),
'open_stamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'quantity': ('django.db.models.fields.IntegerField', [], {}),
'type': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
'unit_price': ('django.db.models.fields.FloatField', [], {})
},
'market.transaction': {
'Meta': {'object_name': 'Transaction'},
'buy_order': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'buy_transactions'", 'to': "orm['market.MarketOrder']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'quantity': ('django.db.models.fields.IntegerField', [], {}),
'sell_order': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sell_transactions'", 'to': "orm['market.MarketOrder']"}),
'stamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
},
'minecraft.item': {
'Meta': {'object_name': 'Item'},
'damage': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'data': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'material': ('django.db.models.fields.IntegerField', [], {'default': '0'})
}
}
complete_apps = ['market']

View File

145
market/models.py Normal file
View File

@@ -0,0 +1,145 @@
from django.db import models
from django.conf import settings
from django.db import transaction
from django.db.models import F
from datetime import datetime
from django.db.models.signals import post_save
from api.events import queue_market_event, MarketOrderEvent
from vault.models import VaultSlot
from django.contrib.auth.models import User
from minecraft.items import ITEMS
from minecraft.models import Item
import logging
OFFER_TYPE = (
(-1, 'Sell'),
(1, 'Buy'),
)
log = logging.getLogger(__name__)
class TransactionError(Exception):
pass
class MarketOrder(models.Model):
item = models.ForeignKey(Item)
creator = models.ForeignKey(User)
unit_price = models.FloatField()
open_stamp = models.DateTimeField(auto_now_add=True)
close_stamp = models.DateTimeField(null=True, blank=True)
initial_quantity = models.IntegerField(blank=True)
quantity = models.IntegerField()
type = models.IntegerField(default=-1, choices = OFFER_TYPE)
def __unicode__(self):
return "%s %s %s %s @%s/ea"%(self.creator, self.get_type_display(),
self.quantity, self.item, self.unit_price)
@staticmethod
def lowest_price(item):
orders = MarketOrder.objects.filter(item=item, quantity__gt=0)
lowestPrice = None
for o in orders:
if lowestPrice is None or o.unit_price < lowestPrice:
lowestPrice = o.unit_price
return lowestPrice
@staticmethod
def highest_price(item):
orders = MarketOrder.objects.filter(item=item, quantity__gt=0)
highestPrice = None
for o in orders:
if highestPrice is None or o.unit_price > highestPrice:
highestPrice = o.unit_price
return highestPrice
def total_price(self):
return self.quantity * self.unit_price
class Meta:
ordering = ['-open_stamp', 'unit_price']
def save(self, *args, **kwargs):
if self.close_stamp is None and self.quantity == 0:
self.close_stamp = datetime.now()
if not self.initial_quantity:
self.initial_quantity = self.quantity
super(MarketOrder, self).save(*args, **kwargs)
def enqueue_process(self):
if settings.CAMINUS_USE_BEANSTALKD:
evt = MarketOrderEvent(self.id)
queue_market_event(evt)
else:
self.process()
@transaction.commit_on_success
def process(self):
if self.quantity == 0:
return
log.debug("Processing Order %d:", self.id)
log.debug("\tItem: %s", self.item)
log.debug("\tQuantity: %d", self.quantity)
log.debug("\tUnit price: %d", self.unit_price)
log.debug("\tTotal price: %d", self.total_price())
matchingOrders = MarketOrder.objects.filter(item=self.item,
unit_price=self.unit_price, type=-self.type,
quantity__gt=0)
for match in matchingOrders:
if self.type == 1:
buyOrder = MarketOrder.objects.get(pk=self.pk)
sellOrder = MarketOrder.objects.get(pk=match.pk)
else:
buyOrder = MarketOrder.objects.get(pk=match.pk)
sellOrder = MarketOrder.objects.get(pk=self.pk)
try:
Transaction.create(buy_order=buyOrder,
sell_order=sellOrder)
except TransactionError, e:
log.exception("Couldn't process transaction", e)
def process_order(sender, instance, created, **kwargs):
if created:
instance.enqueue_process()
post_save.connect(process_order, sender=MarketOrder)
class Transaction(models.Model):
buy_order = models.ForeignKey(MarketOrder, related_name='buy_transactions')
sell_order = models.ForeignKey(MarketOrder, related_name='sell_transactions')
quantity = models.IntegerField()
stamp = models.DateTimeField(auto_now_add=True)
@staticmethod
@transaction.commit_on_success
def create(buy_order, sell_order, quantity=None):
buyerFunds = buy_order.creator.minecraftprofile.currencyaccount
sellerFunds = sell_order.creator.minecraftprofile.currencyaccount
if quantity is None:
quantity = min(float(buyerFunds.balance) / sell_order.unit_price,
buy_order.quantity, buy_order.quantity)
purchaseCost = buy_order.unit_price * quantity
if purchaseCost > buyerFunds.balance:
raise TransactionError, "Insufficient funds."
buy_order.quantity = F('quantity')-quantity
sell_order.quantity = F('quantity')-quantity
buyerFunds.balance = F('balance')-purchaseCost
sellerFunds.balance = F('balance')+purchaseCost
log.info("%s buying %d from %s for %d", buy_order.creator,
quantity, sell_order.creator, purchaseCost)
buyerFunds.save()
sellerFunds.save()
buy_order.save()
sell_order.save()
VaultSlot.addToInventory(buy_order.creator.minecraftprofile, buy_order.item,
quantity)
return Transaction.objects.create(buy_order=buy_order, sell_order=sell_order,
quantity=quantity)

16
market/tests.py Normal file
View File

@@ -0,0 +1,16 @@
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
Replace this with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.assertEqual(1 + 1, 2)

9
market/urls.py Normal file
View File

@@ -0,0 +1,9 @@
from django.conf.urls.defaults import patterns, include, url
urlpatterns = patterns('market',
url(r'^$', 'views.index'),
url(r'^buy$', 'views.buy'),
url(r'^buy/(?P<orderID>[0-9]+)$', 'views.buy'),
url(r'^sell$', 'views.sell'),
url(r'^item/(?P<itemID>[0-9]+)$', 'views.itemStats'),
)

54
market/views.py Normal file
View File

@@ -0,0 +1,54 @@
import models
from minecraft.models import Item
from datetime import datetime
from django.contrib import messages
from django.shortcuts import render
from django.template import RequestContext
from vault.models import VaultSlot
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
def index(request):
buy_orders = models.MarketOrder.objects.filter(type=1,
quantity__gt=0)
sell_orders = models.MarketOrder.objects.filter(type=-1,
quantity__gt=0)
items = Item.objects.all()
marketData = []
for i in items:
data = {}
data['item'] = i
data['high'] = models.MarketOrder.highest_price(i)
data['low'] = models.MarketOrder.lowest_price(i)
marketData.append(data)
return render(request, 'market/index.html', {'buy_orders': buy_orders, 'sell_orders':
sell_orders, 'items': marketData})
def buy(request, orderID=None):
if orderID:
order = models.MarketOrder.objects.get(id=orderID, type=-1)
if order.quantity == 0:
messages.info(request, "That order is already closed.")
else:
buyOrder = models.MarketOrder.objects.create(item=order.item,
creator=request.user, unit_price=order.unit_price,
quantity=order.quantity, type=1)
messages.info(request, "Order queued.")
return HttpResponseRedirect(reverse('market.views.itemStats', kwargs={'itemID':
order.item.id}))
return render(request, 'market/buy.html', {'form': None})
def sell(request):
return render(request, 'market/sell.html', {'form': None})
def itemStats(request, itemID):
item = Item.objects.get(id=itemID)
buy_orders = models.MarketOrder.objects.filter(type=1,
quantity__gt=0, item=item)
sell_orders = models.MarketOrder.objects.filter(type=-1,
quantity__gt=0, item=item)
return render(request, 'market/item.html', {'item': item, 'high':
models.MarketOrder.highest_price(item), 'low':
models.MarketOrder.lowest_price(item), 'buy_orders': buy_orders,
'sell_orders': sell_orders})

View File

@@ -140,6 +140,7 @@ INSTALLED_APPS = (
'donate',
'badges',
'vault',
'market',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
)

View File

@@ -125,6 +125,7 @@ s.parentNode.insertBefore(po, s);
</div>
<ul>
<li><a href="/">Home</a></li>
<li><a href="{%url 'market.views.index' %}">Market</a></li>
<li><a href="{%url 'local.views.list' %}">User List</a></li>
<li><a href="{% url 'petition.views.create' %}">Create Petition</a></li>
<li><a href="{% url 'donate.views.index' %}">Donate!</a></li>

View File

@@ -0,0 +1,63 @@
{% extends 'base_simple.html' %}
{% block title %}The Market{% endblock %}
{% block sectiontitle %}The Market{% endblock %}
{% block content %}
<h2>Market Prices</h2>
<table>
<tr>
<th>Item</th>
<th>High</th>
<th>Low</th>
</tr>
{% for itemData in items %}
<tr>
<td>
<a href="{% url market.views.itemStats itemID=itemData.item.id%}">
{% include 'common/item.html' with item=itemData.item %}
</a>
</td>
<td>{{itemData.high}}</td>
<td>{{itemDta.low}}</td>
</tr>
{% endfor %}
</table>
<h2>Sell Orders</h2>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Total Price</th>
<th>Action</th>
</tr>
{% for order in sell_orders %}
<tr>
<td><a href="{% url market.views.itemStats itemID=order.item.id%}">{{order.item}}</a></td>
<td>{{order.quantity}}</td>
<td>{{order.unit_price}}</td>
<td>{{order.total_price}}</td>
<td><a href="{% url market.views.buy orderID=order.id %}">Buy Now</a></td>
</tr>
{% endfor %}
</table>
<h2>Buy Orders</h2>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Total Price</th>
</tr>
{% for order in buy_orders %}
<tr>
<td>{{order.item}}</td>
<td>{{order.quantity}}</td>
<td>{{order.unit_price}}</td>
<td>{{order.total_price}}</td>
</tr>
{% endfor %}
</table>
{% endblock %}

View File

@@ -0,0 +1,53 @@
{% extends 'base_simple.html' %}
{% block title %}Market Details{% endblock %}
{% block sectiontitle %}The Market{% endblock %}
{% block breadcrumb %}
Home
&gt; <a href="{% url market.views.index %}">Market</a>
&gt; {{item.name}}
{% endblock %}
{% block content %}
{% include 'common/item.html' with item=item %}
<table>
<tr><th>High</th><th>Low</th></tr>
<tr><td>{{high}}</td><td>{{low}}</td></tr>
</table>
<h2>Sell Orders</h2>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Total Price</th>
<th>Action</th>
</tr>
{% for order in sell_orders %}
<tr>
<td><a href="{% url market.views.itemStats itemID=order.item.id%}">{{order.item}}</a></td>
<td>{{order.quantity}}</td>
<td>{{order.unit_price}}</td>
<td>{{order.total_price}}</td>
<td><a href="{% url market.views.buy orderID=order.id %}">Buy Now</a></td>
</tr>
{% endfor %}
</table>
<h2>Buy Orders</h2>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Total Price</th>
</tr>
{% for order in buy_orders %}
<tr>
<td>{{order.item}}</td>
<td>{{order.quantity}}</td>
<td>{{order.unit_price}}</td>
<td>{{order.total_price}}</td>
</tr>
{% endfor %}
</table>
{% endblock %}

View File

@@ -26,6 +26,7 @@ urlpatterns = patterns('',
url(r'^badges/', include('badges.urls')),
url(r'^bounty/', include('bounty.urls')),
url(r'^vault/', include('vault.urls')),
url(r'^market/', include('market.urls')),
)
urlpatterns += staticfiles_urlpatterns()